Open
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
42 changes: 33 additions & 9 deletions src/coreclr/jit/compiler.hpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -933,7 +933,7 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
// Assumptions:
// The mask contains one and only one register.

inline regNumber genRegNumFromMask(regMaskTP mask)
inline regNumber genRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

Expand All@@ -947,6 +947,27 @@ inline regNumber genRegNumFromMask(regMaskTP mask)
return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
//

inline regNumber genFirstRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
Expand All@@ -964,30 +985,33 @@ inline regNumber genFirstRegNumFromMaskAndToggle(regMaskTP& mask)

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)genFirstRegNumFromMask(mask);

mask ^= genRegMask(regNum);
mask ^= regNum;

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
// The number of the first register contained in the mask and updates the `mask` to toggle
// the bit.
//

inline regNumber genFirstRegNumFromMask(regMaskTP mask)
inline regNumber genFirstRegNumFromMaskAndToggle(SingleTypeRegSet& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)BitOperations::BitScanForward(mask);

mask ^= genRegMask(regNum);

return regNum;
}
Expand Down
13 changes: 7 additions & 6 deletions src/coreclr/jit/lsra.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4022,7 +4022,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
{
RefPosition* nextKill = killRefPosition->nextRefPosition;

regMaskTP killedRegs = killRefPosition->registerAssignment;
SingleTypeRegSet killedRegs = killRefPosition->registerAssignment;
while (killedRegs != RBM_NONE)
{
regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs);
Expand DownExpand Up@@ -4064,7 +4064,7 @@ void LinearScan::spillGCRefs(RefPosition* killRefPosition)
{
// For each physical register that can hold a GC type,
// if it is occupied by an interval of a GC type, spill that interval.
regMaskTP candidateRegs = killRefPosition->registerAssignment;
SingleTypeRegSet candidateRegs = killRefPosition->registerAssignment;
INDEBUG(bool killedRegs = false);
while (candidateRegs != RBM_NONE)
{
Expand DownExpand Up@@ -4157,9 +4157,10 @@ regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber tar
{
// If we're rotating the register locations at block boundaries, try to use
// the next higher register number of the appropriate register type.
regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
SingleTypeRegSet candidateRegs =
allRegs(interval->registerType) & availableRegs.GetRegSetForType(interval->registerType);
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand DownExpand Up@@ -12182,7 +12183,7 @@ void LinearScan::verifyFinalAllocation()
// However, we will assert that, at resolution time, no registers contain GC refs.
{
DBEXEC(VERBOSE, printf(" "));
regMaskTP candidateRegs = currentRefPosition.registerAssignment;
SingleTypeRegSet candidateRegs = currentRefPosition.registerAssignment;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand Down
17 changes: 13 additions & 4 deletions src/coreclr/jit/lsrabuild.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2825,14 +2825,23 @@ void LinearScan::buildIntervals()
availableRegCount = REG_INT_COUNT;
}

if (availableRegCount < (sizeof(regMaskTP) * 8))
static_assert(sizeof(regMaskTP) == 2 * sizeof(regMaskSmall));

if (availableRegCount < (sizeof(regMaskSmall) * 8))
{
// Mask out the bits that are between (8 * regMaskSmall) ~ availableRegCount
actualRegistersMask = regMaskTP((1ULL << availableRegCount) - 1);
}
else if (availableRegCount < (sizeof(regMaskTP) * 8))
{
// Mask out the bits that are between 64 ~ availableRegCount
actualRegistersMask = (1ULL << availableRegCount) - 1;
// Mask out the bits that are between (8 * regMaskTP) ~ availableRegCount
// Subtract one extra for stack.
unsigned topRegCount = availableRegCount - sizeof(regMaskSmall) * 8 - 1;
actualRegistersMask = regMaskTP(~RBM_NONE, (1ULL << topRegCount) - 1);
}
else
{
actualRegistersMask = ~RBM_NONE;
actualRegistersMask = regMaskTP(~RBM_NONE, ~RBM_NONE);
}

#ifdef DEBUG
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/regset.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,7 +119,7 @@ class RegSet
bool rsRegsModified(regMaskTP mask) const
{
assert(rsModifiedRegsMaskInitialized);
return (rsModifiedRegsMask & mask) != 0;
return (rsModifiedRegsMask & mask).IsNonEmpty();
}

void verifyRegUsed(regNumber reg);
Expand Down
76 changes: 43 additions & 33 deletions src/coreclr/jit/target.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -229,14 +229,25 @@ typedef uint64_t regMaskSmall;
#define REG_MASK_ALL_FMT "%016llX"
#endif

typedef regMaskSmall SingleTypeRegSet;
typedef regMaskSmall SingleTypeRegSet;
inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

struct regMaskTP
{
private:
regMaskSmall low;
regMaskSmall high;

public:
constexpr regMaskTP(regMaskSmall regMask)

regMaskTP(regMaskSmall lowMask, regMaskSmall highMask)
: low(lowMask)
, high(highMask)
{
}

regMaskTP(regMaskSmall regMask)
: low(regMask)
{
}
Expand DownExpand Up@@ -278,12 +289,12 @@ struct regMaskTP
return low;
}

bool IsEmpty()
bool IsEmpty() const
{
return low == RBM_NONE;
}

bool IsNonEmpty()
bool IsNonEmpty() const
{
return !IsEmpty();
}
Expand All@@ -296,50 +307,52 @@ struct regMaskTP
void RemoveRegNumFromMask(regNumber reg);

bool IsRegNumInMask(regNumber reg);

void operator|=(const regMaskTP& second)
{
low |= second.getLow();
}

void operator^=(const regMaskTP& second)
{
low ^= second.getLow();
}

void operator^=(const regNumber reg)
{
low ^= genRegMask(reg);
}

void operator&=(const regMaskTP& second)
{
low &= second.getLow();
}
};

static regMaskTP operator^(regMaskTP first, regMaskTP second)
static regMaskTP operator^(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() ^ second.getLow());
return result;
}

static regMaskTP operator&(regMaskTP first, regMaskTP second)
static regMaskTP operator&(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() & second.getLow());
return result;
}

static regMaskTP operator|(regMaskTP first, regMaskTP second)
static regMaskTP operator|(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() | second.getLow());
return result;
}

static regMaskTP& operator|=(regMaskTP& first, regMaskTP second)
{
first = first | second;
return first;
}

static regMaskTP& operator^=(regMaskTP& first, regMaskTP second)
{
first = first ^ second;
return first;
}

static regMaskTP& operator&=(regMaskTP& first, regMaskTP second)
{
first = first & second;
return first;
}

static bool operator==(regMaskTP first, regMaskTP second)
static bool operator==(const regMaskTP& first, const regMaskTP& second)
{
return (first.getLow() == second.getLow());
}

static bool operator!=(regMaskTP first, regMaskTP second)
static bool operator!=(const regMaskTP& first, const regMaskTP& second)
{
return !(first == second);
}
Expand DownExpand Up@@ -375,18 +388,18 @@ static regMaskTP& operator<<=(regMaskTP& first, const int b)
}
#endif

static regMaskTP operator~(regMaskTP first)
static regMaskTP operator~(const regMaskTP& first)
{
regMaskTP result(~first.getLow());
return result;
}

static uint32_t PopCount(regMaskTP value)
static uint32_t PopCount(const regMaskTP& value)
{
return BitOperations::PopCount(value.getLow());
}

static uint32_t BitScanForward(regMaskTP mask)
static uint32_t BitScanForward(const regMaskTP& mask)
{
return BitOperations::BitScanForward(mask.getLow());
}
Expand DownExpand Up@@ -508,9 +521,6 @@ inline bool isByteReg(regNumber reg)
}
#endif

inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

/*****************************************************************************
* Return true if the register number is valid
*/
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Open
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
42 changes: 33 additions & 9 deletions src/coreclr/jit/compiler.hpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -933,7 +933,7 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
// Assumptions:
// The mask contains one and only one register.

inline regNumber genRegNumFromMask(regMaskTP mask)
inline regNumber genRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

Expand All@@ -947,6 +947,27 @@ inline regNumber genRegNumFromMask(regMaskTP mask)
return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
//

inline regNumber genFirstRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
Expand All@@ -964,30 +985,33 @@ inline regNumber genFirstRegNumFromMaskAndToggle(regMaskTP& mask)

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)genFirstRegNumFromMask(mask);

mask ^= genRegMask(regNum);
mask ^= regNum;

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
// The number of the first register contained in the mask and updates the `mask` to toggle
// the bit.
//

inline regNumber genFirstRegNumFromMask(regMaskTP mask)
inline regNumber genFirstRegNumFromMaskAndToggle(SingleTypeRegSet& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)BitOperations::BitScanForward(mask);

mask ^= genRegMask(regNum);

return regNum;
}
Expand Down
13 changes: 7 additions & 6 deletions src/coreclr/jit/lsra.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4022,7 +4022,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
{
RefPosition* nextKill = killRefPosition->nextRefPosition;

regMaskTP killedRegs = killRefPosition->registerAssignment;
SingleTypeRegSet killedRegs = killRefPosition->registerAssignment;
while (killedRegs != RBM_NONE)
{
regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs);
Expand DownExpand Up@@ -4064,7 +4064,7 @@ void LinearScan::spillGCRefs(RefPosition* killRefPosition)
{
// For each physical register that can hold a GC type,
// if it is occupied by an interval of a GC type, spill that interval.
regMaskTP candidateRegs = killRefPosition->registerAssignment;
SingleTypeRegSet candidateRegs = killRefPosition->registerAssignment;
INDEBUG(bool killedRegs = false);
while (candidateRegs != RBM_NONE)
{
Expand DownExpand Up@@ -4157,9 +4157,10 @@ regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber tar
{
// If we're rotating the register locations at block boundaries, try to use
// the next higher register number of the appropriate register type.
regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
SingleTypeRegSet candidateRegs =
allRegs(interval->registerType) & availableRegs.GetRegSetForType(interval->registerType);
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand DownExpand Up@@ -12182,7 +12183,7 @@ void LinearScan::verifyFinalAllocation()
// However, we will assert that, at resolution time, no registers contain GC refs.
{
DBEXEC(VERBOSE, printf(" "));
regMaskTP candidateRegs = currentRefPosition.registerAssignment;
SingleTypeRegSet candidateRegs = currentRefPosition.registerAssignment;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand Down
17 changes: 13 additions & 4 deletions src/coreclr/jit/lsrabuild.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2825,14 +2825,23 @@ void LinearScan::buildIntervals()
availableRegCount = REG_INT_COUNT;
}

if (availableRegCount < (sizeof(regMaskTP) * 8))
static_assert(sizeof(regMaskTP) == 2 * sizeof(regMaskSmall));

if (availableRegCount < (sizeof(regMaskSmall) * 8))
{
// Mask out the bits that are between (8 * regMaskSmall) ~ availableRegCount
actualRegistersMask = regMaskTP((1ULL << availableRegCount) - 1);
}
else if (availableRegCount < (sizeof(regMaskTP) * 8))
{
// Mask out the bits that are between 64 ~ availableRegCount
actualRegistersMask = (1ULL << availableRegCount) - 1;
// Mask out the bits that are between (8 * regMaskTP) ~ availableRegCount
// Subtract one extra for stack.
unsigned topRegCount = availableRegCount - sizeof(regMaskSmall) * 8 - 1;
actualRegistersMask = regMaskTP(~RBM_NONE, (1ULL << topRegCount) - 1);
}
else
{
actualRegistersMask = ~RBM_NONE;
actualRegistersMask = regMaskTP(~RBM_NONE, ~RBM_NONE);
}

#ifdef DEBUG
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/regset.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,7 +119,7 @@ class RegSet
bool rsRegsModified(regMaskTP mask) const
{
assert(rsModifiedRegsMaskInitialized);
return (rsModifiedRegsMask & mask) != 0;
return (rsModifiedRegsMask & mask).IsNonEmpty();
}

void verifyRegUsed(regNumber reg);
Expand Down
76 changes: 43 additions & 33 deletions src/coreclr/jit/target.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -229,14 +229,25 @@ typedef uint64_t regMaskSmall;
#define REG_MASK_ALL_FMT "%016llX"
#endif

typedef regMaskSmall SingleTypeRegSet;
typedef regMaskSmall SingleTypeRegSet;
inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

struct regMaskTP
{
private:
regMaskSmall low;
regMaskSmall high;

public:
constexpr regMaskTP(regMaskSmall regMask)

regMaskTP(regMaskSmall lowMask, regMaskSmall highMask)
: low(lowMask)
, high(highMask)
{
}

regMaskTP(regMaskSmall regMask)
: low(regMask)
{
}
Expand DownExpand Up@@ -278,12 +289,12 @@ struct regMaskTP
return low;
}

bool IsEmpty()
bool IsEmpty() const
{
return low == RBM_NONE;
}

bool IsNonEmpty()
bool IsNonEmpty() const
{
return !IsEmpty();
}
Expand All@@ -296,50 +307,52 @@ struct regMaskTP
void RemoveRegNumFromMask(regNumber reg);

bool IsRegNumInMask(regNumber reg);

void operator|=(const regMaskTP& second)
{
low |= second.getLow();
}

void operator^=(const regMaskTP& second)
{
low ^= second.getLow();
}

void operator^=(const regNumber reg)
{
low ^= genRegMask(reg);
}

void operator&=(const regMaskTP& second)
{
low &= second.getLow();
}
};

static regMaskTP operator^(regMaskTP first, regMaskTP second)
static regMaskTP operator^(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() ^ second.getLow());
return result;
}

static regMaskTP operator&(regMaskTP first, regMaskTP second)
static regMaskTP operator&(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() & second.getLow());
return result;
}

static regMaskTP operator|(regMaskTP first, regMaskTP second)
static regMaskTP operator|(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() | second.getLow());
return result;
}

static regMaskTP& operator|=(regMaskTP& first, regMaskTP second)
{
first = first | second;
return first;
}

static regMaskTP& operator^=(regMaskTP& first, regMaskTP second)
{
first = first ^ second;
return first;
}

static regMaskTP& operator&=(regMaskTP& first, regMaskTP second)
{
first = first & second;
return first;
}

static bool operator==(regMaskTP first, regMaskTP second)
static bool operator==(const regMaskTP& first, const regMaskTP& second)
{
return (first.getLow() == second.getLow());
}

static bool operator!=(regMaskTP first, regMaskTP second)
static bool operator!=(const regMaskTP& first, const regMaskTP& second)
{
return !(first == second);
}
Expand DownExpand Up@@ -375,18 +388,18 @@ static regMaskTP& operator<<=(regMaskTP& first, const int b)
}
#endif

static regMaskTP operator~(regMaskTP first)
static regMaskTP operator~(const regMaskTP& first)
{
regMaskTP result(~first.getLow());
return result;
}

static uint32_t PopCount(regMaskTP value)
static uint32_t PopCount(const regMaskTP& value)
{
return BitOperations::PopCount(value.getLow());
}

static uint32_t BitScanForward(regMaskTP mask)
static uint32_t BitScanForward(const regMaskTP& mask)
{
return BitOperations::BitScanForward(mask.getLow());
}
Expand DownExpand Up@@ -508,9 +521,6 @@ inline bool isByteReg(regNumber reg)
}
#endif

inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

/*****************************************************************************
* Return true if the register number is valid
*/
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
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
42 changes: 33 additions & 9 deletions src/coreclr/jit/compiler.hpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -933,7 +933,7 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
// Assumptions:
// The mask contains one and only one register.

inline regNumber genRegNumFromMask(regMaskTP mask)
inline regNumber genRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

Expand All@@ -947,6 +947,27 @@ inline regNumber genRegNumFromMask(regMaskTP mask)
return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
//

inline regNumber genFirstRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
Expand All@@ -964,30 +985,33 @@ inline regNumber genFirstRegNumFromMaskAndToggle(regMaskTP& mask)

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)genFirstRegNumFromMask(mask);

mask ^= genRegMask(regNum);
mask ^= regNum;

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
// The number of the first register contained in the mask and updates the `mask` to toggle
// the bit.
//

inline regNumber genFirstRegNumFromMask(regMaskTP mask)
inline regNumber genFirstRegNumFromMaskAndToggle(SingleTypeRegSet& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)BitOperations::BitScanForward(mask);

mask ^= genRegMask(regNum);

return regNum;
}
Expand Down
13 changes: 7 additions & 6 deletions src/coreclr/jit/lsra.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4022,7 +4022,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
{
RefPosition* nextKill = killRefPosition->nextRefPosition;

regMaskTP killedRegs = killRefPosition->registerAssignment;
SingleTypeRegSet killedRegs = killRefPosition->registerAssignment;
while (killedRegs != RBM_NONE)
{
regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs);
Expand DownExpand Up@@ -4064,7 +4064,7 @@ void LinearScan::spillGCRefs(RefPosition* killRefPosition)
{
// For each physical register that can hold a GC type,
// if it is occupied by an interval of a GC type, spill that interval.
regMaskTP candidateRegs = killRefPosition->registerAssignment;
SingleTypeRegSet candidateRegs = killRefPosition->registerAssignment;
INDEBUG(bool killedRegs = false);
while (candidateRegs != RBM_NONE)
{
Expand DownExpand Up@@ -4157,9 +4157,10 @@ regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber tar
{
// If we're rotating the register locations at block boundaries, try to use
// the next higher register number of the appropriate register type.
regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
SingleTypeRegSet candidateRegs =
allRegs(interval->registerType) & availableRegs.GetRegSetForType(interval->registerType);
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand DownExpand Up@@ -12182,7 +12183,7 @@ void LinearScan::verifyFinalAllocation()
// However, we will assert that, at resolution time, no registers contain GC refs.
{
DBEXEC(VERBOSE, printf(" "));
regMaskTP candidateRegs = currentRefPosition.registerAssignment;
SingleTypeRegSet candidateRegs = currentRefPosition.registerAssignment;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand Down
17 changes: 13 additions & 4 deletions src/coreclr/jit/lsrabuild.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2825,14 +2825,23 @@ void LinearScan::buildIntervals()
availableRegCount = REG_INT_COUNT;
}

if (availableRegCount < (sizeof(regMaskTP) * 8))
static_assert(sizeof(regMaskTP) == 2 * sizeof(regMaskSmall));

if (availableRegCount < (sizeof(regMaskSmall) * 8))
{
// Mask out the bits that are between (8 * regMaskSmall) ~ availableRegCount
actualRegistersMask = regMaskTP((1ULL << availableRegCount) - 1);
}
else if (availableRegCount < (sizeof(regMaskTP) * 8))
{
// Mask out the bits that are between 64 ~ availableRegCount
actualRegistersMask = (1ULL << availableRegCount) - 1;
// Mask out the bits that are between (8 * regMaskTP) ~ availableRegCount
// Subtract one extra for stack.
unsigned topRegCount = availableRegCount - sizeof(regMaskSmall) * 8 - 1;
actualRegistersMask = regMaskTP(~RBM_NONE, (1ULL << topRegCount) - 1);
}
else
{
actualRegistersMask = ~RBM_NONE;
actualRegistersMask = regMaskTP(~RBM_NONE, ~RBM_NONE);
}

#ifdef DEBUG
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/regset.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,7 +119,7 @@ class RegSet
bool rsRegsModified(regMaskTP mask) const
{
assert(rsModifiedRegsMaskInitialized);
return (rsModifiedRegsMask & mask) != 0;
return (rsModifiedRegsMask & mask).IsNonEmpty();
}

void verifyRegUsed(regNumber reg);
Expand Down
76 changes: 43 additions & 33 deletions src/coreclr/jit/target.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -229,14 +229,25 @@ typedef uint64_t regMaskSmall;
#define REG_MASK_ALL_FMT "%016llX"
#endif

typedef regMaskSmall SingleTypeRegSet;
typedef regMaskSmall SingleTypeRegSet;
inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

struct regMaskTP
{
private:
regMaskSmall low;
regMaskSmall high;

public:
constexpr regMaskTP(regMaskSmall regMask)

regMaskTP(regMaskSmall lowMask, regMaskSmall highMask)
: low(lowMask)
, high(highMask)
{
}

regMaskTP(regMaskSmall regMask)
: low(regMask)
{
}
Expand DownExpand Up@@ -278,12 +289,12 @@ struct regMaskTP
return low;
}

bool IsEmpty()
bool IsEmpty() const
{
return low == RBM_NONE;
}

bool IsNonEmpty()
bool IsNonEmpty() const
{
return !IsEmpty();
}
Expand All@@ -296,50 +307,52 @@ struct regMaskTP
void RemoveRegNumFromMask(regNumber reg);

bool IsRegNumInMask(regNumber reg);

void operator|=(const regMaskTP& second)
{
low |= second.getLow();
}

void operator^=(const regMaskTP& second)
{
low ^= second.getLow();
}

void operator^=(const regNumber reg)
{
low ^= genRegMask(reg);
}

void operator&=(const regMaskTP& second)
{
low &= second.getLow();
}
};

static regMaskTP operator^(regMaskTP first, regMaskTP second)
static regMaskTP operator^(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() ^ second.getLow());
return result;
}

static regMaskTP operator&(regMaskTP first, regMaskTP second)
static regMaskTP operator&(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() & second.getLow());
return result;
}

static regMaskTP operator|(regMaskTP first, regMaskTP second)
static regMaskTP operator|(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() | second.getLow());
return result;
}

static regMaskTP& operator|=(regMaskTP& first, regMaskTP second)
{
first = first | second;
return first;
}

static regMaskTP& operator^=(regMaskTP& first, regMaskTP second)
{
first = first ^ second;
return first;
}

static regMaskTP& operator&=(regMaskTP& first, regMaskTP second)
{
first = first & second;
return first;
}

static bool operator==(regMaskTP first, regMaskTP second)
static bool operator==(const regMaskTP& first, const regMaskTP& second)
{
return (first.getLow() == second.getLow());
}

static bool operator!=(regMaskTP first, regMaskTP second)
static bool operator!=(const regMaskTP& first, const regMaskTP& second)
{
return !(first == second);
}
Expand DownExpand Up@@ -375,18 +388,18 @@ static regMaskTP& operator<<=(regMaskTP& first, const int b)
}
#endif

static regMaskTP operator~(regMaskTP first)
static regMaskTP operator~(const regMaskTP& first)
{
regMaskTP result(~first.getLow());
return result;
}

static uint32_t PopCount(regMaskTP value)
static uint32_t PopCount(const regMaskTP& value)
{
return BitOperations::PopCount(value.getLow());
}

static uint32_t BitScanForward(regMaskTP mask)
static uint32_t BitScanForward(const regMaskTP& mask)
{
return BitOperations::BitScanForward(mask.getLow());
}
Expand DownExpand Up@@ -508,9 +521,6 @@ inline bool isByteReg(regNumber reg)
}
#endif

inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

/*****************************************************************************
* Return true if the register number is valid
*/
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
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
42 changes: 33 additions & 9 deletions src/coreclr/jit/compiler.hpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -933,7 +933,7 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
// Assumptions:
// The mask contains one and only one register.

inline regNumber genRegNumFromMask(regMaskTP mask)
inline regNumber genRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

Expand All@@ -947,6 +947,27 @@ inline regNumber genRegNumFromMask(regMaskTP mask)
return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
//

inline regNumber genFirstRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
Expand All@@ -964,30 +985,33 @@ inline regNumber genFirstRegNumFromMaskAndToggle(regMaskTP& mask)

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)genFirstRegNumFromMask(mask);

mask ^= genRegMask(regNum);
mask ^= regNum;

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
// The number of the first register contained in the mask and updates the `mask` to toggle
// the bit.
//

inline regNumber genFirstRegNumFromMask(regMaskTP mask)
inline regNumber genFirstRegNumFromMaskAndToggle(SingleTypeRegSet& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)BitOperations::BitScanForward(mask);

mask ^= genRegMask(regNum);

return regNum;
}
Expand Down
13 changes: 7 additions & 6 deletions src/coreclr/jit/lsra.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4022,7 +4022,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
{
RefPosition* nextKill = killRefPosition->nextRefPosition;

regMaskTP killedRegs = killRefPosition->registerAssignment;
SingleTypeRegSet killedRegs = killRefPosition->registerAssignment;
while (killedRegs != RBM_NONE)
{
regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs);
Expand DownExpand Up@@ -4064,7 +4064,7 @@ void LinearScan::spillGCRefs(RefPosition* killRefPosition)
{
// For each physical register that can hold a GC type,
// if it is occupied by an interval of a GC type, spill that interval.
regMaskTP candidateRegs = killRefPosition->registerAssignment;
SingleTypeRegSet candidateRegs = killRefPosition->registerAssignment;
INDEBUG(bool killedRegs = false);
while (candidateRegs != RBM_NONE)
{
Expand DownExpand Up@@ -4157,9 +4157,10 @@ regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber tar
{
// If we're rotating the register locations at block boundaries, try to use
// the next higher register number of the appropriate register type.
regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
SingleTypeRegSet candidateRegs =
allRegs(interval->registerType) & availableRegs.GetRegSetForType(interval->registerType);
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand DownExpand Up@@ -12182,7 +12183,7 @@ void LinearScan::verifyFinalAllocation()
// However, we will assert that, at resolution time, no registers contain GC refs.
{
DBEXEC(VERBOSE, printf(" "));
regMaskTP candidateRegs = currentRefPosition.registerAssignment;
SingleTypeRegSet candidateRegs = currentRefPosition.registerAssignment;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand Down
17 changes: 13 additions & 4 deletions src/coreclr/jit/lsrabuild.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2825,14 +2825,23 @@ void LinearScan::buildIntervals()
availableRegCount = REG_INT_COUNT;
}

if (availableRegCount < (sizeof(regMaskTP) * 8))
static_assert(sizeof(regMaskTP) == 2 * sizeof(regMaskSmall));

if (availableRegCount < (sizeof(regMaskSmall) * 8))
{
// Mask out the bits that are between (8 * regMaskSmall) ~ availableRegCount
actualRegistersMask = regMaskTP((1ULL << availableRegCount) - 1);
}
else if (availableRegCount < (sizeof(regMaskTP) * 8))
{
// Mask out the bits that are between 64 ~ availableRegCount
actualRegistersMask = (1ULL << availableRegCount) - 1;
// Mask out the bits that are between (8 * regMaskTP) ~ availableRegCount
// Subtract one extra for stack.
unsigned topRegCount = availableRegCount - sizeof(regMaskSmall) * 8 - 1;
actualRegistersMask = regMaskTP(~RBM_NONE, (1ULL << topRegCount) - 1);
}
else
{
actualRegistersMask = ~RBM_NONE;
actualRegistersMask = regMaskTP(~RBM_NONE, ~RBM_NONE);
}

#ifdef DEBUG
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/regset.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,7 +119,7 @@ class RegSet
bool rsRegsModified(regMaskTP mask) const
{
assert(rsModifiedRegsMaskInitialized);
return (rsModifiedRegsMask & mask) != 0;
return (rsModifiedRegsMask & mask).IsNonEmpty();
}

void verifyRegUsed(regNumber reg);
Expand Down
76 changes: 43 additions & 33 deletions src/coreclr/jit/target.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -229,14 +229,25 @@ typedef uint64_t regMaskSmall;
#define REG_MASK_ALL_FMT "%016llX"
#endif

typedef regMaskSmall SingleTypeRegSet;
typedef regMaskSmall SingleTypeRegSet;
inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

struct regMaskTP
{
private:
regMaskSmall low;
regMaskSmall high;

public:
constexpr regMaskTP(regMaskSmall regMask)

regMaskTP(regMaskSmall lowMask, regMaskSmall highMask)
: low(lowMask)
, high(highMask)
{
}

regMaskTP(regMaskSmall regMask)
: low(regMask)
{
}
Expand DownExpand Up@@ -278,12 +289,12 @@ struct regMaskTP
return low;
}

bool IsEmpty()
bool IsEmpty() const
{
return low == RBM_NONE;
}

bool IsNonEmpty()
bool IsNonEmpty() const
{
return !IsEmpty();
}
Expand All@@ -296,50 +307,52 @@ struct regMaskTP
void RemoveRegNumFromMask(regNumber reg);

bool IsRegNumInMask(regNumber reg);

void operator|=(const regMaskTP& second)
{
low |= second.getLow();
}

void operator^=(const regMaskTP& second)
{
low ^= second.getLow();
}

void operator^=(const regNumber reg)
{
low ^= genRegMask(reg);
}

void operator&=(const regMaskTP& second)
{
low &= second.getLow();
}
};

static regMaskTP operator^(regMaskTP first, regMaskTP second)
static regMaskTP operator^(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() ^ second.getLow());
return result;
}

static regMaskTP operator&(regMaskTP first, regMaskTP second)
static regMaskTP operator&(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() & second.getLow());
return result;
}

static regMaskTP operator|(regMaskTP first, regMaskTP second)
static regMaskTP operator|(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() | second.getLow());
return result;
}

static regMaskTP& operator|=(regMaskTP& first, regMaskTP second)
{
first = first | second;
return first;
}

static regMaskTP& operator^=(regMaskTP& first, regMaskTP second)
{
first = first ^ second;
return first;
}

static regMaskTP& operator&=(regMaskTP& first, regMaskTP second)
{
first = first & second;
return first;
}

static bool operator==(regMaskTP first, regMaskTP second)
static bool operator==(const regMaskTP& first, const regMaskTP& second)
{
return (first.getLow() == second.getLow());
}

static bool operator!=(regMaskTP first, regMaskTP second)
static bool operator!=(const regMaskTP& first, const regMaskTP& second)
{
return !(first == second);
}
Expand DownExpand Up@@ -375,18 +388,18 @@ static regMaskTP& operator<<=(regMaskTP& first, const int b)
}
#endif

static regMaskTP operator~(regMaskTP first)
static regMaskTP operator~(const regMaskTP& first)
{
regMaskTP result(~first.getLow());
return result;
}

static uint32_t PopCount(regMaskTP value)
static uint32_t PopCount(const regMaskTP& value)
{
return BitOperations::PopCount(value.getLow());
}

static uint32_t BitScanForward(regMaskTP mask)
static uint32_t BitScanForward(const regMaskTP& mask)
{
return BitOperations::BitScanForward(mask.getLow());
}
Expand DownExpand Up@@ -508,9 +521,6 @@ inline bool isByteReg(regNumber reg)
}
#endif

inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

/*****************************************************************************
* Return true if the register number is valid
*/
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Open
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
42 changes: 33 additions & 9 deletions src/coreclr/jit/compiler.hpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -933,7 +933,7 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
// Assumptions:
// The mask contains one and only one register.

inline regNumber genRegNumFromMask(regMaskTP mask)
inline regNumber genRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

Expand All@@ -947,6 +947,27 @@ inline regNumber genRegNumFromMask(regMaskTP mask)
return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
//

inline regNumber genFirstRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
Expand All@@ -964,30 +985,33 @@ inline regNumber genFirstRegNumFromMaskAndToggle(regMaskTP& mask)

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)genFirstRegNumFromMask(mask);

mask ^= genRegMask(regNum);
mask ^= regNum;

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
// The number of the first register contained in the mask and updates the `mask` to toggle
// the bit.
//

inline regNumber genFirstRegNumFromMask(regMaskTP mask)
inline regNumber genFirstRegNumFromMaskAndToggle(SingleTypeRegSet& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)BitOperations::BitScanForward(mask);

mask ^= genRegMask(regNum);

return regNum;
}
Expand Down
13 changes: 7 additions & 6 deletions src/coreclr/jit/lsra.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4022,7 +4022,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
{
RefPosition* nextKill = killRefPosition->nextRefPosition;

regMaskTP killedRegs = killRefPosition->registerAssignment;
SingleTypeRegSet killedRegs = killRefPosition->registerAssignment;
while (killedRegs != RBM_NONE)
{
regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs);
Expand DownExpand Up@@ -4064,7 +4064,7 @@ void LinearScan::spillGCRefs(RefPosition* killRefPosition)
{
// For each physical register that can hold a GC type,
// if it is occupied by an interval of a GC type, spill that interval.
regMaskTP candidateRegs = killRefPosition->registerAssignment;
SingleTypeRegSet candidateRegs = killRefPosition->registerAssignment;
INDEBUG(bool killedRegs = false);
while (candidateRegs != RBM_NONE)
{
Expand DownExpand Up@@ -4157,9 +4157,10 @@ regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber tar
{
// If we're rotating the register locations at block boundaries, try to use
// the next higher register number of the appropriate register type.
regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
SingleTypeRegSet candidateRegs =
allRegs(interval->registerType) & availableRegs.GetRegSetForType(interval->registerType);
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand DownExpand Up@@ -12182,7 +12183,7 @@ void LinearScan::verifyFinalAllocation()
// However, we will assert that, at resolution time, no registers contain GC refs.
{
DBEXEC(VERBOSE, printf(" "));
regMaskTP candidateRegs = currentRefPosition.registerAssignment;
SingleTypeRegSet candidateRegs = currentRefPosition.registerAssignment;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand Down
17 changes: 13 additions & 4 deletions src/coreclr/jit/lsrabuild.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2825,14 +2825,23 @@ void LinearScan::buildIntervals()
availableRegCount = REG_INT_COUNT;
}

if (availableRegCount < (sizeof(regMaskTP) * 8))
static_assert(sizeof(regMaskTP) == 2 * sizeof(regMaskSmall));

if (availableRegCount < (sizeof(regMaskSmall) * 8))
{
// Mask out the bits that are between (8 * regMaskSmall) ~ availableRegCount
actualRegistersMask = regMaskTP((1ULL << availableRegCount) - 1);
}
else if (availableRegCount < (sizeof(regMaskTP) * 8))
{
// Mask out the bits that are between 64 ~ availableRegCount
actualRegistersMask = (1ULL << availableRegCount) - 1;
// Mask out the bits that are between (8 * regMaskTP) ~ availableRegCount
// Subtract one extra for stack.
unsigned topRegCount = availableRegCount - sizeof(regMaskSmall) * 8 - 1;
actualRegistersMask = regMaskTP(~RBM_NONE, (1ULL << topRegCount) - 1);
}
else
{
actualRegistersMask = ~RBM_NONE;
actualRegistersMask = regMaskTP(~RBM_NONE, ~RBM_NONE);
}

#ifdef DEBUG
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/regset.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,7 +119,7 @@ class RegSet
bool rsRegsModified(regMaskTP mask) const
{
assert(rsModifiedRegsMaskInitialized);
return (rsModifiedRegsMask & mask) != 0;
return (rsModifiedRegsMask & mask).IsNonEmpty();
}

void verifyRegUsed(regNumber reg);
Expand Down
76 changes: 43 additions & 33 deletions src/coreclr/jit/target.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -229,14 +229,25 @@ typedef uint64_t regMaskSmall;
#define REG_MASK_ALL_FMT "%016llX"
#endif

typedef regMaskSmall SingleTypeRegSet;
typedef regMaskSmall SingleTypeRegSet;
inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

struct regMaskTP
{
private:
regMaskSmall low;
regMaskSmall high;

public:
constexpr regMaskTP(regMaskSmall regMask)

regMaskTP(regMaskSmall lowMask, regMaskSmall highMask)
: low(lowMask)
, high(highMask)
{
}

regMaskTP(regMaskSmall regMask)
: low(regMask)
{
}
Expand DownExpand Up@@ -278,12 +289,12 @@ struct regMaskTP
return low;
}

bool IsEmpty()
bool IsEmpty() const
{
return low == RBM_NONE;
}

bool IsNonEmpty()
bool IsNonEmpty() const
{
return !IsEmpty();
}
Expand All@@ -296,50 +307,52 @@ struct regMaskTP
void RemoveRegNumFromMask(regNumber reg);

bool IsRegNumInMask(regNumber reg);

void operator|=(const regMaskTP& second)
{
low |= second.getLow();
}

void operator^=(const regMaskTP& second)
{
low ^= second.getLow();
}

void operator^=(const regNumber reg)
{
low ^= genRegMask(reg);
}

void operator&=(const regMaskTP& second)
{
low &= second.getLow();
}
};

static regMaskTP operator^(regMaskTP first, regMaskTP second)
static regMaskTP operator^(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() ^ second.getLow());
return result;
}

static regMaskTP operator&(regMaskTP first, regMaskTP second)
static regMaskTP operator&(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() & second.getLow());
return result;
}

static regMaskTP operator|(regMaskTP first, regMaskTP second)
static regMaskTP operator|(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() | second.getLow());
return result;
}

static regMaskTP& operator|=(regMaskTP& first, regMaskTP second)
{
first = first | second;
return first;
}

static regMaskTP& operator^=(regMaskTP& first, regMaskTP second)
{
first = first ^ second;
return first;
}

static regMaskTP& operator&=(regMaskTP& first, regMaskTP second)
{
first = first & second;
return first;
}

static bool operator==(regMaskTP first, regMaskTP second)
static bool operator==(const regMaskTP& first, const regMaskTP& second)
{
return (first.getLow() == second.getLow());
}

static bool operator!=(regMaskTP first, regMaskTP second)
static bool operator!=(const regMaskTP& first, const regMaskTP& second)
{
return !(first == second);
}
Expand DownExpand Up@@ -375,18 +388,18 @@ static regMaskTP& operator<<=(regMaskTP& first, const int b)
}
#endif

static regMaskTP operator~(regMaskTP first)
static regMaskTP operator~(const regMaskTP& first)
{
regMaskTP result(~first.getLow());
return result;
}

static uint32_t PopCount(regMaskTP value)
static uint32_t PopCount(const regMaskTP& value)
{
return BitOperations::PopCount(value.getLow());
}

static uint32_t BitScanForward(regMaskTP mask)
static uint32_t BitScanForward(const regMaskTP& mask)
{
return BitOperations::BitScanForward(mask.getLow());
}
Expand DownExpand Up@@ -508,9 +521,6 @@ inline bool isByteReg(regNumber reg)
}
#endif

inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

/*****************************************************************************
* Return true if the register number is valid
*/
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
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
42 changes: 33 additions & 9 deletions src/coreclr/jit/compiler.hpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -933,7 +933,7 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
// Assumptions:
// The mask contains one and only one register.

inline regNumber genRegNumFromMask(regMaskTP mask)
inline regNumber genRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

Expand All@@ -947,6 +947,27 @@ inline regNumber genRegNumFromMask(regMaskTP mask)
return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
//

inline regNumber genFirstRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
Expand All@@ -964,30 +985,33 @@ inline regNumber genFirstRegNumFromMaskAndToggle(regMaskTP& mask)

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)genFirstRegNumFromMask(mask);

mask ^= genRegMask(regNum);
mask ^= regNum;

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
// The number of the first register contained in the mask and updates the `mask` to toggle
// the bit.
//

inline regNumber genFirstRegNumFromMask(regMaskTP mask)
inline regNumber genFirstRegNumFromMaskAndToggle(SingleTypeRegSet& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)BitOperations::BitScanForward(mask);

mask ^= genRegMask(regNum);

return regNum;
}
Expand Down
13 changes: 7 additions & 6 deletions src/coreclr/jit/lsra.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4022,7 +4022,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
{
RefPosition* nextKill = killRefPosition->nextRefPosition;

regMaskTP killedRegs = killRefPosition->registerAssignment;
SingleTypeRegSet killedRegs = killRefPosition->registerAssignment;
while (killedRegs != RBM_NONE)
{
regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs);
Expand DownExpand Up@@ -4064,7 +4064,7 @@ void LinearScan::spillGCRefs(RefPosition* killRefPosition)
{
// For each physical register that can hold a GC type,
// if it is occupied by an interval of a GC type, spill that interval.
regMaskTP candidateRegs = killRefPosition->registerAssignment;
SingleTypeRegSet candidateRegs = killRefPosition->registerAssignment;
INDEBUG(bool killedRegs = false);
while (candidateRegs != RBM_NONE)
{
Expand DownExpand Up@@ -4157,9 +4157,10 @@ regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber tar
{
// If we're rotating the register locations at block boundaries, try to use
// the next higher register number of the appropriate register type.
regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
SingleTypeRegSet candidateRegs =
allRegs(interval->registerType) & availableRegs.GetRegSetForType(interval->registerType);
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand DownExpand Up@@ -12182,7 +12183,7 @@ void LinearScan::verifyFinalAllocation()
// However, we will assert that, at resolution time, no registers contain GC refs.
{
DBEXEC(VERBOSE, printf(" "));
regMaskTP candidateRegs = currentRefPosition.registerAssignment;
SingleTypeRegSet candidateRegs = currentRefPosition.registerAssignment;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand Down
17 changes: 13 additions & 4 deletions src/coreclr/jit/lsrabuild.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2825,14 +2825,23 @@ void LinearScan::buildIntervals()
availableRegCount = REG_INT_COUNT;
}

if (availableRegCount < (sizeof(regMaskTP) * 8))
static_assert(sizeof(regMaskTP) == 2 * sizeof(regMaskSmall));

if (availableRegCount < (sizeof(regMaskSmall) * 8))
{
// Mask out the bits that are between (8 * regMaskSmall) ~ availableRegCount
actualRegistersMask = regMaskTP((1ULL << availableRegCount) - 1);
}
else if (availableRegCount < (sizeof(regMaskTP) * 8))
{
// Mask out the bits that are between 64 ~ availableRegCount
actualRegistersMask = (1ULL << availableRegCount) - 1;
// Mask out the bits that are between (8 * regMaskTP) ~ availableRegCount
// Subtract one extra for stack.
unsigned topRegCount = availableRegCount - sizeof(regMaskSmall) * 8 - 1;
actualRegistersMask = regMaskTP(~RBM_NONE, (1ULL << topRegCount) - 1);
}
else
{
actualRegistersMask = ~RBM_NONE;
actualRegistersMask = regMaskTP(~RBM_NONE, ~RBM_NONE);
}

#ifdef DEBUG
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/regset.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,7 +119,7 @@ class RegSet
bool rsRegsModified(regMaskTP mask) const
{
assert(rsModifiedRegsMaskInitialized);
return (rsModifiedRegsMask & mask) != 0;
return (rsModifiedRegsMask & mask).IsNonEmpty();
}

void verifyRegUsed(regNumber reg);
Expand Down
76 changes: 43 additions & 33 deletions src/coreclr/jit/target.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -229,14 +229,25 @@ typedef uint64_t regMaskSmall;
#define REG_MASK_ALL_FMT "%016llX"
#endif

typedef regMaskSmall SingleTypeRegSet;
typedef regMaskSmall SingleTypeRegSet;
inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

struct regMaskTP
{
private:
regMaskSmall low;
regMaskSmall high;

public:
constexpr regMaskTP(regMaskSmall regMask)

regMaskTP(regMaskSmall lowMask, regMaskSmall highMask)
: low(lowMask)
, high(highMask)
{
}

regMaskTP(regMaskSmall regMask)
: low(regMask)
{
}
Expand DownExpand Up@@ -278,12 +289,12 @@ struct regMaskTP
return low;
}

bool IsEmpty()
bool IsEmpty() const
{
return low == RBM_NONE;
}

bool IsNonEmpty()
bool IsNonEmpty() const
{
return !IsEmpty();
}
Expand All@@ -296,50 +307,52 @@ struct regMaskTP
void RemoveRegNumFromMask(regNumber reg);

bool IsRegNumInMask(regNumber reg);

void operator|=(const regMaskTP& second)
{
low |= second.getLow();
}

void operator^=(const regMaskTP& second)
{
low ^= second.getLow();
}

void operator^=(const regNumber reg)
{
low ^= genRegMask(reg);
}

void operator&=(const regMaskTP& second)
{
low &= second.getLow();
}
};

static regMaskTP operator^(regMaskTP first, regMaskTP second)
static regMaskTP operator^(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() ^ second.getLow());
return result;
}

static regMaskTP operator&(regMaskTP first, regMaskTP second)
static regMaskTP operator&(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() & second.getLow());
return result;
}

static regMaskTP operator|(regMaskTP first, regMaskTP second)
static regMaskTP operator|(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() | second.getLow());
return result;
}

static regMaskTP& operator|=(regMaskTP& first, regMaskTP second)
{
first = first | second;
return first;
}

static regMaskTP& operator^=(regMaskTP& first, regMaskTP second)
{
first = first ^ second;
return first;
}

static regMaskTP& operator&=(regMaskTP& first, regMaskTP second)
{
first = first & second;
return first;
}

static bool operator==(regMaskTP first, regMaskTP second)
static bool operator==(const regMaskTP& first, const regMaskTP& second)
{
return (first.getLow() == second.getLow());
}

static bool operator!=(regMaskTP first, regMaskTP second)
static bool operator!=(const regMaskTP& first, const regMaskTP& second)
{
return !(first == second);
}
Expand DownExpand Up@@ -375,18 +388,18 @@ static regMaskTP& operator<<=(regMaskTP& first, const int b)
}
#endif

static regMaskTP operator~(regMaskTP first)
static regMaskTP operator~(const regMaskTP& first)
{
regMaskTP result(~first.getLow());
return result;
}

static uint32_t PopCount(regMaskTP value)
static uint32_t PopCount(const regMaskTP& value)
{
return BitOperations::PopCount(value.getLow());
}

static uint32_t BitScanForward(regMaskTP mask)
static uint32_t BitScanForward(const regMaskTP& mask)
{
return BitOperations::BitScanForward(mask.getLow());
}
Expand DownExpand Up@@ -508,9 +521,6 @@ inline bool isByteReg(regNumber reg)
}
#endif

inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

/*****************************************************************************
* Return true if the register number is valid
*/
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
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
42 changes: 33 additions & 9 deletions src/coreclr/jit/compiler.hpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -933,7 +933,7 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
// Assumptions:
// The mask contains one and only one register.

inline regNumber genRegNumFromMask(regMaskTP mask)
inline regNumber genRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

Expand All@@ -947,6 +947,27 @@ inline regNumber genRegNumFromMask(regMaskTP mask)
return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
//

inline regNumber genFirstRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
Expand All@@ -964,30 +985,33 @@ inline regNumber genFirstRegNumFromMaskAndToggle(regMaskTP& mask)

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)genFirstRegNumFromMask(mask);

mask ^= genRegMask(regNum);
mask ^= regNum;

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
// The number of the first register contained in the mask and updates the `mask` to toggle
// the bit.
//

inline regNumber genFirstRegNumFromMask(regMaskTP mask)
inline regNumber genFirstRegNumFromMaskAndToggle(SingleTypeRegSet& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)BitOperations::BitScanForward(mask);

mask ^= genRegMask(regNum);

return regNum;
}
Expand Down
13 changes: 7 additions & 6 deletions src/coreclr/jit/lsra.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4022,7 +4022,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
{
RefPosition* nextKill = killRefPosition->nextRefPosition;

regMaskTP killedRegs = killRefPosition->registerAssignment;
SingleTypeRegSet killedRegs = killRefPosition->registerAssignment;
while (killedRegs != RBM_NONE)
{
regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs);
Expand DownExpand Up@@ -4064,7 +4064,7 @@ void LinearScan::spillGCRefs(RefPosition* killRefPosition)
{
// For each physical register that can hold a GC type,
// if it is occupied by an interval of a GC type, spill that interval.
regMaskTP candidateRegs = killRefPosition->registerAssignment;
SingleTypeRegSet candidateRegs = killRefPosition->registerAssignment;
INDEBUG(bool killedRegs = false);
while (candidateRegs != RBM_NONE)
{
Expand DownExpand Up@@ -4157,9 +4157,10 @@ regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber tar
{
// If we're rotating the register locations at block boundaries, try to use
// the next higher register number of the appropriate register type.
regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
SingleTypeRegSet candidateRegs =
allRegs(interval->registerType) & availableRegs.GetRegSetForType(interval->registerType);
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand DownExpand Up@@ -12182,7 +12183,7 @@ void LinearScan::verifyFinalAllocation()
// However, we will assert that, at resolution time, no registers contain GC refs.
{
DBEXEC(VERBOSE, printf(" "));
regMaskTP candidateRegs = currentRefPosition.registerAssignment;
SingleTypeRegSet candidateRegs = currentRefPosition.registerAssignment;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand Down
17 changes: 13 additions & 4 deletions src/coreclr/jit/lsrabuild.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2825,14 +2825,23 @@ void LinearScan::buildIntervals()
availableRegCount = REG_INT_COUNT;
}

if (availableRegCount < (sizeof(regMaskTP) * 8))
static_assert(sizeof(regMaskTP) == 2 * sizeof(regMaskSmall));

if (availableRegCount < (sizeof(regMaskSmall) * 8))
{
// Mask out the bits that are between (8 * regMaskSmall) ~ availableRegCount
actualRegistersMask = regMaskTP((1ULL << availableRegCount) - 1);
}
else if (availableRegCount < (sizeof(regMaskTP) * 8))
{
// Mask out the bits that are between 64 ~ availableRegCount
actualRegistersMask = (1ULL << availableRegCount) - 1;
// Mask out the bits that are between (8 * regMaskTP) ~ availableRegCount
// Subtract one extra for stack.
unsigned topRegCount = availableRegCount - sizeof(regMaskSmall) * 8 - 1;
actualRegistersMask = regMaskTP(~RBM_NONE, (1ULL << topRegCount) - 1);
}
else
{
actualRegistersMask = ~RBM_NONE;
actualRegistersMask = regMaskTP(~RBM_NONE, ~RBM_NONE);
}

#ifdef DEBUG
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/regset.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,7 +119,7 @@ class RegSet
bool rsRegsModified(regMaskTP mask) const
{
assert(rsModifiedRegsMaskInitialized);
return (rsModifiedRegsMask & mask) != 0;
return (rsModifiedRegsMask & mask).IsNonEmpty();
}

void verifyRegUsed(regNumber reg);
Expand Down
76 changes: 43 additions & 33 deletions src/coreclr/jit/target.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -229,14 +229,25 @@ typedef uint64_t regMaskSmall;
#define REG_MASK_ALL_FMT "%016llX"
#endif

typedef regMaskSmall SingleTypeRegSet;
typedef regMaskSmall SingleTypeRegSet;
inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

struct regMaskTP
{
private:
regMaskSmall low;
regMaskSmall high;

public:
constexpr regMaskTP(regMaskSmall regMask)

regMaskTP(regMaskSmall lowMask, regMaskSmall highMask)
: low(lowMask)
, high(highMask)
{
}

regMaskTP(regMaskSmall regMask)
: low(regMask)
{
}
Expand DownExpand Up@@ -278,12 +289,12 @@ struct regMaskTP
return low;
}

bool IsEmpty()
bool IsEmpty() const
{
return low == RBM_NONE;
}

bool IsNonEmpty()
bool IsNonEmpty() const
{
return !IsEmpty();
}
Expand All@@ -296,50 +307,52 @@ struct regMaskTP
void RemoveRegNumFromMask(regNumber reg);

bool IsRegNumInMask(regNumber reg);

void operator|=(const regMaskTP& second)
{
low |= second.getLow();
}

void operator^=(const regMaskTP& second)
{
low ^= second.getLow();
}

void operator^=(const regNumber reg)
{
low ^= genRegMask(reg);
}

void operator&=(const regMaskTP& second)
{
low &= second.getLow();
}
};

static regMaskTP operator^(regMaskTP first, regMaskTP second)
static regMaskTP operator^(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() ^ second.getLow());
return result;
}

static regMaskTP operator&(regMaskTP first, regMaskTP second)
static regMaskTP operator&(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() & second.getLow());
return result;
}

static regMaskTP operator|(regMaskTP first, regMaskTP second)
static regMaskTP operator|(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() | second.getLow());
return result;
}

static regMaskTP& operator|=(regMaskTP& first, regMaskTP second)
{
first = first | second;
return first;
}

static regMaskTP& operator^=(regMaskTP& first, regMaskTP second)
{
first = first ^ second;
return first;
}

static regMaskTP& operator&=(regMaskTP& first, regMaskTP second)
{
first = first & second;
return first;
}

static bool operator==(regMaskTP first, regMaskTP second)
static bool operator==(const regMaskTP& first, const regMaskTP& second)
{
return (first.getLow() == second.getLow());
}

static bool operator!=(regMaskTP first, regMaskTP second)
static bool operator!=(const regMaskTP& first, const regMaskTP& second)
{
return !(first == second);
}
Expand DownExpand Up@@ -375,18 +388,18 @@ static regMaskTP& operator<<=(regMaskTP& first, const int b)
}
#endif

static regMaskTP operator~(regMaskTP first)
static regMaskTP operator~(const regMaskTP& first)
{
regMaskTP result(~first.getLow());
return result;
}

static uint32_t PopCount(regMaskTP value)
static uint32_t PopCount(const regMaskTP& value)
{
return BitOperations::PopCount(value.getLow());
}

static uint32_t BitScanForward(regMaskTP mask)
static uint32_t BitScanForward(const regMaskTP& mask)
{
return BitOperations::BitScanForward(mask.getLow());
}
Expand DownExpand Up@@ -508,9 +521,6 @@ inline bool isByteReg(regNumber reg)
}
#endif

inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

/*****************************************************************************
* Return true if the register number is valid
*/
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Open
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
42 changes: 33 additions & 9 deletions src/coreclr/jit/compiler.hpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -933,7 +933,7 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
// Assumptions:
// The mask contains one and only one register.

inline regNumber genRegNumFromMask(regMaskTP mask)
inline regNumber genRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

Expand All@@ -947,6 +947,27 @@ inline regNumber genRegNumFromMask(regMaskTP mask)
return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
//

inline regNumber genFirstRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
Expand All@@ -964,30 +985,33 @@ inline regNumber genFirstRegNumFromMaskAndToggle(regMaskTP& mask)

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)genFirstRegNumFromMask(mask);

mask ^= genRegMask(regNum);
mask ^= regNum;

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
// The number of the first register contained in the mask and updates the `mask` to toggle
// the bit.
//

inline regNumber genFirstRegNumFromMask(regMaskTP mask)
inline regNumber genFirstRegNumFromMaskAndToggle(SingleTypeRegSet& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)BitOperations::BitScanForward(mask);

mask ^= genRegMask(regNum);

return regNum;
}
Expand Down
13 changes: 7 additions & 6 deletions src/coreclr/jit/lsra.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4022,7 +4022,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
{
RefPosition* nextKill = killRefPosition->nextRefPosition;

regMaskTP killedRegs = killRefPosition->registerAssignment;
SingleTypeRegSet killedRegs = killRefPosition->registerAssignment;
while (killedRegs != RBM_NONE)
{
regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs);
Expand DownExpand Up@@ -4064,7 +4064,7 @@ void LinearScan::spillGCRefs(RefPosition* killRefPosition)
{
// For each physical register that can hold a GC type,
// if it is occupied by an interval of a GC type, spill that interval.
regMaskTP candidateRegs = killRefPosition->registerAssignment;
SingleTypeRegSet candidateRegs = killRefPosition->registerAssignment;
INDEBUG(bool killedRegs = false);
while (candidateRegs != RBM_NONE)
{
Expand DownExpand Up@@ -4157,9 +4157,10 @@ regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber tar
{
// If we're rotating the register locations at block boundaries, try to use
// the next higher register number of the appropriate register type.
regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
SingleTypeRegSet candidateRegs =
allRegs(interval->registerType) & availableRegs.GetRegSetForType(interval->registerType);
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand DownExpand Up@@ -12182,7 +12183,7 @@ void LinearScan::verifyFinalAllocation()
// However, we will assert that, at resolution time, no registers contain GC refs.
{
DBEXEC(VERBOSE, printf(" "));
regMaskTP candidateRegs = currentRefPosition.registerAssignment;
SingleTypeRegSet candidateRegs = currentRefPosition.registerAssignment;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand Down
17 changes: 13 additions & 4 deletions src/coreclr/jit/lsrabuild.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -2825,14 +2825,23 @@ void LinearScan::buildIntervals()
availableRegCount = REG_INT_COUNT;
}

if (availableRegCount < (sizeof(regMaskTP) * 8))
static_assert(sizeof(regMaskTP) == 2 * sizeof(regMaskSmall));

if (availableRegCount < (sizeof(regMaskSmall) * 8))
{
// Mask out the bits that are between (8 * regMaskSmall) ~ availableRegCount
actualRegistersMask = regMaskTP((1ULL << availableRegCount) - 1);
}
else if (availableRegCount < (sizeof(regMaskTP) * 8))
{
// Mask out the bits that are between 64 ~ availableRegCount
actualRegistersMask = (1ULL << availableRegCount) - 1;
// Mask out the bits that are between (8 * regMaskTP) ~ availableRegCount
// Subtract one extra for stack.
unsigned topRegCount = availableRegCount - sizeof(regMaskSmall) * 8 - 1;
actualRegistersMask = regMaskTP(~RBM_NONE, (1ULL << topRegCount) - 1);
}
else
{
actualRegistersMask = ~RBM_NONE;
actualRegistersMask = regMaskTP(~RBM_NONE, ~RBM_NONE);
}

#ifdef DEBUG
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/regset.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,7 +119,7 @@ class RegSet
bool rsRegsModified(regMaskTP mask) const
{
assert(rsModifiedRegsMaskInitialized);
return (rsModifiedRegsMask & mask) != 0;
return (rsModifiedRegsMask & mask).IsNonEmpty();
}

void verifyRegUsed(regNumber reg);
Expand Down
76 changes: 43 additions & 33 deletions src/coreclr/jit/target.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -229,14 +229,25 @@ typedef uint64_t regMaskSmall;
#define REG_MASK_ALL_FMT "%016llX"
#endif

typedef regMaskSmall SingleTypeRegSet;
typedef regMaskSmall SingleTypeRegSet;
inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

struct regMaskTP
{
private:
regMaskSmall low;
regMaskSmall high;

public:
constexpr regMaskTP(regMaskSmall regMask)

regMaskTP(regMaskSmall lowMask, regMaskSmall highMask)
: low(lowMask)
, high(highMask)
{
}

regMaskTP(regMaskSmall regMask)
: low(regMask)
{
}
Expand DownExpand Up@@ -278,12 +289,12 @@ struct regMaskTP
return low;
}

bool IsEmpty()
bool IsEmpty() const
{
return low == RBM_NONE;
}

bool IsNonEmpty()
bool IsNonEmpty() const
{
return !IsEmpty();
}
Expand All@@ -296,50 +307,52 @@ struct regMaskTP
void RemoveRegNumFromMask(regNumber reg);

bool IsRegNumInMask(regNumber reg);

void operator|=(const regMaskTP& second)
{
low |= second.getLow();
}

void operator^=(const regMaskTP& second)
{
low ^= second.getLow();
}

void operator^=(const regNumber reg)
{
low ^= genRegMask(reg);
}

void operator&=(const regMaskTP& second)
{
low &= second.getLow();
}
};

static regMaskTP operator^(regMaskTP first, regMaskTP second)
static regMaskTP operator^(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() ^ second.getLow());
return result;
}

static regMaskTP operator&(regMaskTP first, regMaskTP second)
static regMaskTP operator&(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() & second.getLow());
return result;
}

static regMaskTP operator|(regMaskTP first, regMaskTP second)
static regMaskTP operator|(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() | second.getLow());
return result;
}

static regMaskTP& operator|=(regMaskTP& first, regMaskTP second)
{
first = first | second;
return first;
}

static regMaskTP& operator^=(regMaskTP& first, regMaskTP second)
{
first = first ^ second;
return first;
}

static regMaskTP& operator&=(regMaskTP& first, regMaskTP second)
{
first = first & second;
return first;
}

static bool operator==(regMaskTP first, regMaskTP second)
static bool operator==(const regMaskTP& first, const regMaskTP& second)
{
return (first.getLow() == second.getLow());
}

static bool operator!=(regMaskTP first, regMaskTP second)
static bool operator!=(const regMaskTP& first, const regMaskTP& second)
{
return !(first == second);
}
Expand DownExpand Up@@ -375,18 +388,18 @@ static regMaskTP& operator<<=(regMaskTP& first, const int b)
}
#endif

static regMaskTP operator~(regMaskTP first)
static regMaskTP operator~(const regMaskTP& first)
{
regMaskTP result(~first.getLow());
return result;
}

static uint32_t PopCount(regMaskTP value)
static uint32_t PopCount(const regMaskTP& value)
{
return BitOperations::PopCount(value.getLow());
}

static uint32_t BitScanForward(regMaskTP mask)
static uint32_t BitScanForward(const regMaskTP& mask)
{
return BitOperations::BitScanForward(mask.getLow());
}
Expand DownExpand Up@@ -508,9 +521,6 @@ inline bool isByteReg(regNumber reg)
}
#endif

inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

/*****************************************************************************
* Return true if the register number is valid
*/
Expand Down