Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3200,7 +3200,7 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
rbmAllInt |= RBM_HIGHINT;
rbmIntCalleeTrash |= RBM_HIGHINT;
cntCalleeTrashInt += CNT_CALLEE_TRASH_HIGHINT;
regIntLast = REG_R23;
regIntLast = REG_R31;
}
#endif // TARGET_AMD64

Expand Down
8 changes: 7 additions & 1 deletion src/coreclr/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,8 +791,10 @@ class emitter
// Note that we use the _idReg1 and _idReg2 fields to hold
// the live gcrefReg mask for the call instructions on x86/x64
//
#if !defined(TARGET_AMD64)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you move this only for x64?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Space taken up to here" comment, below, is now wrong and needs to be updated, as do the "Space taken up to here" comments that follow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you move this only for x64?

It's a bit of a weird problem. REGNUM_BITS changing from 6 to 7 results in _idReg1 and _idReg2 taking up an extra bit each. This throws off the instrDesc size for x64 and increases it significantly due to padding. My solution was to move around the position of _idReg1 and _idReg2 to a position for x64 which did not cause addition of as many padding bits.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why it matters where _idReg1/_idReg2 are placed to determine padding. All type types here have a base type of unsigned which means that bitfields of them should all be able bit packable. It might make sense for performance reasons to avoid splitting _idReg1/_idReg2 across 32-bit (or maybe even byte) boundaries, but that's not why you did it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference

  • In main with no changes
    image

  • If I just add new registers with no change in order for x64
    image

  • With the change highlighted by you in the PR
    image

Copy link
Contributor Author

@DeepakRajendrakumaran DeepakRajendrakumaran Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i leave it as was, _idReg1 cannot stay within 32 bit boundary since it starts at Byte 3, Bit 2(It was not a problem earlier when it was 6 bits). So, it gets moved to Byte 4, Bit 0

Edit - that's my interpretation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see: a bit field can't extend beyond the limit of the base type (here, unsigned).

btw, is the tool your using to show field offsets public?

Copy link
Contributor Author

@DeepakRajendrakumaran DeepakRajendrakumaran Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The screenshot I used here is from Visual Studio. Click on memory layout from below

image

The memory viewer in Visual Studio Code isn't as intuitive

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the "Space taken up to here" comments

regNumber _idReg1 : REGNUM_BITS; // register num
regNumber _idReg2 : REGNUM_BITS;
#endif

////////////////////////////////////////////////////////////////////////
// Space taken up to here:
Expand All @@ -815,6 +817,10 @@ class emitter
unsigned _idCustom1 : 1;
unsigned _idCustom2 : 1;
unsigned _idCustom3 : 1;
#if defined(TARGET_AMD64)
regNumber _idReg1 : REGNUM_BITS; // register num
regNumber _idReg2 : REGNUM_BITS;
#endif

#define _idBound _idCustom1 /* jump target / frame offset bound */
#define _idTlsGD _idCustom2 /* Used to store information related to TLS GD access on linux */
Expand Down Expand Up @@ -900,7 +906,7 @@ class emitter
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
#define ID_EXTRA_BITFIELD_BITS (14)
#elif defined(TARGET_XARCH)
#define ID_EXTRA_BITFIELD_BITS (17)
#define ID_EXTRA_BITFIELD_BITS (19)
#else
#error Unsupported or unset target architecture
#endif
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2529,7 +2529,7 @@ regNumber AbsRegNumber(regNumber reg)
bool IsExtendedReg(regNumber reg)
{
#ifdef TARGET_AMD64
return ((reg >= REG_R8) && (reg <= REG_R23)) || ((reg >= REG_XMM8) && (reg <= REG_XMM31));
return ((reg >= REG_R8) && (reg <= REG_R31)) || ((reg >= REG_XMM8) && (reg <= REG_XMM31));
#else
// X86 JIT operates in 32-bit mode and hence extended reg are not available.
return false;
Expand Down Expand Up @@ -5214,7 +5214,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeSV(instrDesc* id, code_t code, int var
static bool baseRegisterRequiresSibByte(regNumber base)
{
#ifdef TARGET_AMD64
return base == REG_ESP || base == REG_R12 || base == REG_R20;
return base == REG_ESP || base == REG_R12 || base == REG_R20 || base == REG_R28;
#else
return base == REG_ESP;
#endif
Expand All @@ -5223,7 +5223,7 @@ static bool baseRegisterRequiresSibByte(regNumber base)
static bool baseRegisterRequiresDisplacement(regNumber base)
{
#ifdef TARGET_AMD64
return base == REG_EBP || base == REG_R13 || base == REG_R21;
return base == REG_EBP || base == REG_R13 || base == REG_R21 || base == REG_R29;
#else
return base == REG_EBP;
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/emitxarch.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ inline static bool isHighGPReg(regNumber reg)
#ifdef TARGET_AMD64
// TODO-apx: the definition here is incorrect, we will need to revisit this after we extend the register definition.
// for now, we can simply use REX2 as REX.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment still needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have removed this comment

return ((reg >= REG_R16) && (reg <= REG_R23));
return ((reg >= REG_R16) && (reg <= REG_R31));
#else
// X86 JIT operates in 32-bit mode and hence extended regs are not available.
return false;
Expand Down
29 changes: 20 additions & 9 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,8 @@ static const regMaskTP LsraLimitUpperSimdSet =
(RBM_XMM16 | RBM_XMM17 | RBM_XMM18 | RBM_XMM19 | RBM_XMM20 | RBM_XMM21 | RBM_XMM22 | RBM_XMM23 | RBM_XMM24 |
RBM_XMM25 | RBM_XMM26 | RBM_XMM27 | RBM_XMM28 | RBM_XMM29 | RBM_XMM30 | RBM_XMM31);
static const regMaskTP LsraLimitExtGprSet =
(RBM_R16 | RBM_R17 | RBM_R18 | RBM_R19 | RBM_R20 | RBM_R21 | RBM_R22 | RBM_R23 | RBM_ETW_FRAMED_EBP);
(RBM_R16 | RBM_R17 | RBM_R18 | RBM_R19 | RBM_R20 | RBM_R21 | RBM_R22 | RBM_R23 | RBM_R24 | RBM_R25 | RBM_R26 |
RBM_R27 | RBM_R28 | RBM_R29 | RBM_R30 | RBM_R31 | RBM_ETW_FRAMED_EBP);
#elif defined(TARGET_ARM)
// On ARM, we may need two registers to set up the target register for a virtual call, so we need
// to have at least the maximum number of arg registers, plus 2.
Expand Down Expand Up @@ -4285,14 +4286,15 @@ void LinearScan::resetAllRegistersState()
clearAllNextIntervalRef();
clearAllSpillCost();

for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT; reg = REG_NEXT(reg))
for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT;)
{
RegRecord* physRegRecord = getRegisterRecord(reg);
#ifdef DEBUG
Interval* assignedInterval = physRegRecord->assignedInterval;
assert(assignedInterval == nullptr || assignedInterval->isConstant);
#endif
physRegRecord->assignedInterval = nullptr;
reg = physRegRecord->nextRegNum;
}
}

Expand Down Expand Up @@ -4895,12 +4897,13 @@ void LinearScan::allocateRegistersMinimal()
clearAllNextIntervalRef();
clearAllSpillCost();

for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT; reg = REG_NEXT(reg))
for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT;)
{
RegRecord* physRegRecord = getRegisterRecord(reg);
physRegRecord->recentRefPosition = nullptr;
updateNextFixedRefDispatch(physRegRecord, physRegRecord->firstRefPosition, killHead);
assert(physRegRecord->assignedInterval == nullptr);
reg = physRegRecord->nextRegNum;
}

#ifdef DEBUG
Expand Down Expand Up @@ -5558,7 +5561,7 @@ void LinearScan::allocateRegisters()
#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE

resetRegState();
for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT; reg = REG_NEXT(reg))
for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT;)
{
RegRecord* physRegRecord = getRegisterRecord(reg);
physRegRecord->recentRefPosition = nullptr;
Expand All @@ -5584,6 +5587,7 @@ void LinearScan::allocateRegisters()
clearNextIntervalRef(reg, physRegRecord->registerType);
clearSpillCost(reg, physRegRecord->registerType);
}
reg = physRegRecord->nextRegNum;
}

#ifdef DEBUG
Expand Down Expand Up @@ -7877,7 +7881,7 @@ void LinearScan::resolveRegisters()
// are encountered.
if (localVarsEnregistered)
{
for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT; reg = REG_NEXT(reg))
for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT;)
{
RegRecord* physRegRecord = getRegisterRecord(reg);
Interval* assignedInterval = physRegRecord->assignedInterval;
Expand All @@ -7888,6 +7892,7 @@ void LinearScan::resolveRegisters()
}
physRegRecord->assignedInterval = nullptr;
physRegRecord->recentRefPosition = nullptr;
reg = physRegRecord->nextRegNum;
}

// Clear "recentRefPosition" for lclVar intervals
Expand Down Expand Up @@ -11802,17 +11807,18 @@ bool LinearScan::IsResolutionNode(LIR::Range& containingRange, GenTree* node)
//
void LinearScan::verifyFreeRegisters(regMaskTP regsToFree)
{
for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT; reg = REG_NEXT(reg))
for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT;)
{
regMaskTP regMask = genRegMask(reg);
regMaskTP regMask = genRegMask(reg);
RegRecord* physRegRecord = getRegisterRecord(reg);
// If this isn't available or if it's still waiting to be freed (i.e. it was in
// delayRegsToFree and so now it's in regsToFree), then skip it.
if ((regMask & allAvailableRegs & ~regsToFree).IsEmpty())
{
reg = physRegRecord->nextRegNum;
continue;
}
RegRecord* physRegRecord = getRegisterRecord(reg);
Interval* assignedInterval = physRegRecord->assignedInterval;
Interval* assignedInterval = physRegRecord->assignedInterval;
if (assignedInterval != nullptr)
{
bool isAssignedReg = (assignedInterval->physReg == reg);
Expand All @@ -11823,6 +11829,7 @@ void LinearScan::verifyFreeRegisters(regMaskTP regsToFree)
{
if (recentRefPosition->refType == RefTypeExpUse)
{
reg = physRegRecord->nextRegNum;
// We don't update anything on these, as they're just placeholders to extend the
// lifetime.
continue;
Expand All @@ -11831,6 +11838,7 @@ void LinearScan::verifyFreeRegisters(regMaskTP regsToFree)
// For copyReg or moveReg, we don't have anything further to assert.
if (recentRefPosition->copyReg || recentRefPosition->moveReg)
{
reg = physRegRecord->nextRegNum;
continue;
}
assert(assignedInterval->isConstant == isRegConstant(reg, assignedInterval->registerType));
Expand Down Expand Up @@ -11898,6 +11906,9 @@ void LinearScan::verifyFreeRegisters(regMaskTP regsToFree)
{
reg = REG_NEXT(reg);
}
reg = REG_NEXT(reg);
#else
reg = physRegRecord->nextRegNum;
#endif
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/lsra.h
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ class RegRecord : public Referenceable
}
#endif // FEATURE_MASKED_HW_INTRINSICS
regNum = reg;
nextRegNum = REG_NEXT(regNum);
isCalleeSave = ((RBM_CALLEE_SAVED & genRegMask(reg)) != 0);
}

Expand All @@ -544,6 +545,7 @@ class RegRecord : public Referenceable
Interval* previousInterval;

regNumber regNum;
regNumber nextRegNum; // the next active register.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is adding additional 288 bytes of memory per method compilation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you take a stab at #112959 (comment) and see if that is cheap?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not try the regIndices method. I forgot about it. Is this what you had in mind?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming you fix the ACTUAL_REG_COUNT in the else portion of isApxSupported, yes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACTUAL_REG_COUNT

I didn't change ACTUAL_REG_COUNT because I don't think that can be used as the condition as presently used.

The loops look like the following

for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT; reg = REG_NEXT(reg))
{
..............
}

AVAILABLE_REG_COUNT can be either of following

  • ACTUAL_REG_COUNT

or

  • ACTUAL_REG_COUNT - (CNT_HIGHFLOAT + CNT_MASK_REGS)

I ended up not changing ACTUAL_REG_COUNT but rather modifying the loop

int index = 1;
for (regNumber reg = (regNumber)regIndices[0]; reg < AVAILABLE_REG_COUNT; reg = (regNumber)regIndices[index++])
{
    ........................
}

This allows me to keep using AVAILABLE_REG_COUNT

Alternative would be to update ACTUAL_REG_COUNT and use it directly in the for loops

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you update it to be something like and that way you are not affecting non-xarch platform? Also, you don't need separate activeRegsCount in that case.

#ifdef TARGET_XARCH
#define NEXT_REGISTER(i) i++, reg = regIndices[i]
#else
#define NEXT_REGISTER(reg) REG_NEXT(reg)
#endif

for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT; reg = NEXT_REGISTER(reg)) { ... }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't work as is. We will need to track an index and a reg. Reason is on x64, if i understand what you propose correctly, the following will happen

when reg - REG_R15 (value = 15)

reg = NEXT_REGISTER(reg) will result in reg - Reg_XMM0(value = 32)

The next time we do NEXT_REGISTER(reg), this will then result in us looking up regIndices[32] which will then point to REG_XMM17

Would something like the following make sense??

// REGISTER_LOOKUP : a lookup table to match register indice to active registers.
#ifdef TARGET_AMD64
#define REGISTER_LOOKUP(regIndex) regIndices[(unsigned)regIndex]
#else
#define REGISTER_LOOKUP(regIndex) regIndex
#endif
regNumber regIndex = REG_FIRST;
for (regNumber reg = REGISTER_LOOKUP(regIndex); reg < AVAILABLE_REG_COUNT; regIndex = REG_NEXT(regIndex), reg = REGISTER_LOOKUP(regIndex))
{
...................
}

I imagine for non x64, this will get optimized to

regNumber regIndex = REG_FIRST;
for (regNumber reg = regIndex ; reg < AVAILABLE_REG_COUNT; regIndex = REG_NEXT(regIndex), reg = regIndex)
{
...................
}

and then


for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT; reg= REG_NEXT(reg))
{
...................
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes, that's right. May be you can do something like this then?

#ifdef TARGET_XARCH
#define NEXT_REGISTER(reg, index) index++, reg = regIndices[index]
#else
#define NEXT_REGISTER(reg, index) REG_NEXT(reg)
#endif

int index = 0;

for (regNumber reg = REG_FIRST; reg < AVAILABLE_REG_COUNT; reg = NEXT_REGISTER(reg, index)) { ... }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I do that, reg = NEXT_REGISTER(reg, index) will resolve to the following for `x64)

reg = index++, reg = regIndices[index]

Which is why I did the following

Definition and usage

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kunalspathak I have made the requested changes

bool isCalleeSave;
unsigned char regOrder;
};
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/lsrabuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1936,6 +1936,10 @@ void LinearScan::buildPhysRegRecords()
RegRecord* curr = &physRegs[reg];
curr->init(reg);
}
#if defined(TARGET_AMD64)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this fall out naturally? Or are there cases where REG_NEXT(get_REG_INT_LAST()) != REG_FP_FIRST?

Should this be all-platform (no ifdef)?

Copy link
Contributor Author

@DeepakRajendrakumaran DeepakRajendrakumaran Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a x64 specific issue. There are 2 cases

  1. x64 with APX ON
    get_REG_INT_LAST() = REG_R31 and so REG_NEXT(get_REG_INT_LAST()) = REG_FP_FIRST
  2. x64 with APX OFF
    get_REG_INT_LAST() = REG_R15 and so REG_NEXT(get_REG_INT_LAST()) != REG_FP_FIRST
    This is because REG_NEXT(get_REG_INT_LAST()) = REG_R16. REG_R16 is defined but not valid for x64 targets with no APX support

RegRecord* lastInt = &physRegs[get_REG_INT_LAST()];
lastInt->nextRegNum = REG_FP_FIRST;
#endif // TARGET_AMD64
for (unsigned int i = 0; i < lsraRegOrderSize; i++)
{
regNumber reg = lsraRegOrder[i];
Expand Down
79 changes: 52 additions & 27 deletions src/coreclr/jit/register.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,32 +36,41 @@ REGALIAS(RDI, EDI)

#else // !defined(TARGET_X86)

#define GPRMASK(x) (1ULL << (x))
/*
REGDEF(name, rnum, mask, sname) */
REGDEF(RAX, 0, 0x00000001, "rax" )
REGDEF(RCX, 1, 0x00000002, "rcx" )
REGDEF(RDX, 2, 0x00000004, "rdx" )
REGDEF(RBX, 3, 0x00000008, "rbx" )
REGDEF(RSP, 4, 0x00000010, "rsp" )
REGDEF(RBP, 5, 0x00000020, "rbp" )
REGDEF(RSI, 6, 0x00000040, "rsi" )
REGDEF(RDI, 7, 0x00000080, "rdi" )
REGDEF(R8, 8, 0x00000100, "r8" )
REGDEF(R9, 9, 0x00000200, "r9" )
REGDEF(R10, 10, 0x00000400, "r10" )
REGDEF(R11, 11, 0x00000800, "r11" )
REGDEF(R12, 12, 0x00001000, "r12" )
REGDEF(R13, 13, 0x00002000, "r13" )
REGDEF(R14, 14, 0x00004000, "r14" )
REGDEF(R15, 15, 0x00008000, "r15" )
REGDEF(R16, 16, 0x00010000, "r16" )
REGDEF(R17, 17, 0x00020000, "r17" )
REGDEF(R18, 18, 0x00040000, "r18" )
REGDEF(R19, 19, 0x00080000, "r19" )
REGDEF(R20, 20, 0x00100000, "r20" )
REGDEF(R21, 21, 0x00200000, "r21" )
REGDEF(R22, 22, 0x00400000, "r22" )
REGDEF(R23, 23, 0x00800000, "r23" )
REGDEF(RAX, 0, GPRMASK(0), "rax" )
REGDEF(RCX, 1, GPRMASK(1), "rcx" )
REGDEF(RDX, 2, GPRMASK(2), "rdx" )
REGDEF(RBX, 3, GPRMASK(3), "rbx" )
REGDEF(RSP, 4, GPRMASK(4), "rsp" )
REGDEF(RBP, 5, GPRMASK(5), "rbp" )
REGDEF(RSI, 6, GPRMASK(6), "rsi" )
REGDEF(RDI, 7, GPRMASK(7), "rdi" )
REGDEF(R8, 8, GPRMASK(8), "r8" )
REGDEF(R9, 9, GPRMASK(9), "r9" )
REGDEF(R10, 10, GPRMASK(10), "r10" )
REGDEF(R11, 11, GPRMASK(11), "r11" )
REGDEF(R12, 12, GPRMASK(12), "r12" )
REGDEF(R13, 13, GPRMASK(13), "r13" )
REGDEF(R14, 14, GPRMASK(14), "r14" )
REGDEF(R15, 15, GPRMASK(15), "r15" )
REGDEF(R16, 16, GPRMASK(16), "r16" )
REGDEF(R17, 17, GPRMASK(17), "r17" )
REGDEF(R18, 18, GPRMASK(18), "r18" )
REGDEF(R19, 19, GPRMASK(19), "r19" )
REGDEF(R20, 20, GPRMASK(20), "r20" )
REGDEF(R21, 21, GPRMASK(21), "r21" )
REGDEF(R22, 22, GPRMASK(22), "r22" )
REGDEF(R23, 23, GPRMASK(23), "r23" )
REGDEF(R24, 24, GPRMASK(24), "r24" )
REGDEF(R25, 25, GPRMASK(25), "r25" )
REGDEF(R26, 26, GPRMASK(26), "r26" )
REGDEF(R27, 27, GPRMASK(27), "r27" )
REGDEF(R28, 28, GPRMASK(28), "r28" )
REGDEF(R29, 29, GPRMASK(29), "r29" )
REGDEF(R30, 30, GPRMASK(30), "r30" )
REGDEF(R31, 31, GPRMASK(31), "r31" )

REGALIAS(EAX, RAX)
REGALIAS(ECX, RCX)
Expand All @@ -75,11 +84,11 @@ REGALIAS(EDI, RDI)
#endif // !defined(TARGET_X86)

#ifdef TARGET_AMD64
#define XMMBASE 24
#define XMMBASE 32
#define XMMMASK(x) (1ULL << ((x)+XMMBASE))

#define KBASE 56
#define KMASK(x) (1ULL << ((x)+KBASE))
#define KBASE 64
#define KMASK(x) (1ULL << ((x)))

#else // !TARGET_AMD64
#define XMMBASE 8
Expand Down Expand Up @@ -224,6 +233,22 @@ REGDEF(STK, 8+KBASE, 0x0000, "STK" )
#define REG_R22 JITREG_R22
#undef REG_R23
#define REG_R23 JITREG_R23
#undef REG_R24
#define REG_R24 JITREG_R24
#undef REG_R25
#define REG_R25 JITREG_R25
#undef REG_R26
#define REG_R26 JITREG_R26
#undef REG_R27
#define REG_R27 JITREG_R27
#undef REG_R28
#define REG_R28 JITREG_R28
#undef REG_R29
#define REG_R29 JITREG_R29
#undef REG_R30
#define REG_R30 JITREG_R30
#undef REG_R31
#define REG_R31 JITREG_R31
#undef REG_EAX
#define REG_EAX JITREG_EAX
#undef REG_ECX
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ typedef uint64_t regMaskSmall;
#define HAS_MORE_THAN_64_REGISTERS 1
#endif // TARGET_ARM64

#ifdef TARGET_AMD64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge with ARM64 case above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

#define HAS_MORE_THAN_64_REGISTERS 1
#endif // TARGET_AMD64

#define REG_LOW_BASE 0
#ifdef HAS_MORE_THAN_64_REGISTERS
#define REG_HIGH_BASE 64
Expand Down
Loading
Loading