Skip to content

Commit

Permalink
Merge 62e013a into 5522656
Browse files Browse the repository at this point in the history
  • Loading branch information
theRealAph committed Nov 17, 2023
2 parents 5522656 + 62e013a commit 8258852
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 27 deletions.
8 changes: 4 additions & 4 deletions src/hotspot/cpu/x86/register_x86.hpp
Expand Up @@ -391,27 +391,27 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl {

template <>
inline Register AbstractRegSet<Register>::first() {
uint32_t first = _bitset & -_bitset;
size_t first = _bitset & -_bitset;
return first ? as_Register(exact_log2(first)) : noreg;
}

template <>
inline Register AbstractRegSet<Register>::last() {
if (_bitset == 0) { return noreg; }
uint32_t last = 31 - count_leading_zeros(_bitset);
size_t last = max_size() - 1 - count_leading_zeros(_bitset);
return as_Register(last);
}

template <>
inline XMMRegister AbstractRegSet<XMMRegister>::first() {
uint32_t first = _bitset & -_bitset;
size_t first = _bitset & -_bitset;
return first ? as_XMMRegister(exact_log2(first)) : xnoreg;
}

template <>
inline XMMRegister AbstractRegSet<XMMRegister>::last() {
if (_bitset == 0) { return xnoreg; }
uint32_t last = 31 - count_leading_zeros(_bitset);
size_t last = max_size() - 1 - count_leading_zeros(_bitset);
return as_XMMRegister(last);
}

Expand Down
84 changes: 61 additions & 23 deletions src/hotspot/share/asm/register.hpp
Expand Up @@ -93,67 +93,75 @@ template <class RegImpl> class ReverseRegSetIterator;
// A set of registers
template <class RegImpl>
class AbstractRegSet {
uint32_t _bitset;
size_t _bitset;

AbstractRegSet(uint32_t bitset) : _bitset(bitset) { }
constexpr AbstractRegSet(size_t bitset) : _bitset(bitset) { }

static constexpr int max_size() {
return (int)(sizeof _bitset * CHAR_BIT);
}

public:

AbstractRegSet() : _bitset(0) { }
constexpr AbstractRegSet() : _bitset(0) { }

AbstractRegSet(RegImpl r1) : _bitset(1 << r1->encoding()) { }
constexpr AbstractRegSet(RegImpl r1)
: _bitset(r1->is_valid() ? size_t(1) << r1->encoding() : 0) { }

AbstractRegSet operator+(const AbstractRegSet aSet) const {
constexpr AbstractRegSet operator+(const AbstractRegSet aSet) const {
AbstractRegSet result(_bitset | aSet._bitset);
return result;
}

AbstractRegSet operator-(const AbstractRegSet aSet) const {
constexpr AbstractRegSet operator-(const AbstractRegSet aSet) const {
AbstractRegSet result(_bitset & ~aSet._bitset);
return result;
}

AbstractRegSet &operator+=(const AbstractRegSet aSet) {
constexpr AbstractRegSet &operator+=(const AbstractRegSet aSet) {
*this = *this + aSet;
return *this;
}

AbstractRegSet &operator-=(const AbstractRegSet aSet) {
constexpr AbstractRegSet &operator-=(const AbstractRegSet aSet) {
*this = *this - aSet;
return *this;
}

static AbstractRegSet of(RegImpl r1) {
constexpr static AbstractRegSet of(RegImpl r1) {
return AbstractRegSet(r1);
}

static AbstractRegSet of(RegImpl r1, RegImpl r2) {
constexpr static AbstractRegSet of(RegImpl r1, RegImpl r2) {
return of(r1) + r2;
}

static AbstractRegSet of(RegImpl r1, RegImpl r2, RegImpl r3) {
constexpr static AbstractRegSet of(RegImpl r1, RegImpl r2, RegImpl r3) {
return of(r1, r2) + r3;
}

static AbstractRegSet of(RegImpl r1, RegImpl r2, RegImpl r3, RegImpl r4) {
constexpr static AbstractRegSet of(RegImpl r1, RegImpl r2, RegImpl r3, RegImpl r4) {
return of(r1, r2, r3) + r4;
}

static AbstractRegSet range(RegImpl start, RegImpl end) {
constexpr static AbstractRegSet range(RegImpl start, RegImpl end) {
int start_enc = start->encoding();
int end_enc = end->encoding();
assert(start_enc <= end_enc, "must be");
uint32_t bits = ~0;
size_t bits = ~(size_t)0;
bits <<= start_enc;
bits <<= 31 - end_enc;
bits >>= 31 - end_enc;
bits <<= max_size() - 1 - end_enc;
bits >>= max_size() - 1 - end_enc;

return AbstractRegSet(bits);
}

uint size() const { return population_count(_bitset); }
constexpr bool contains(RegImpl reg) {
return (AbstractRegSet(reg).bits() & bits()) != 0;
}

uint32_t bits() const { return _bitset; }
constexpr uint size() const { return population_count(_bitset); }
constexpr size_t bits() const { return _bitset; }

private:

Expand Down Expand Up @@ -245,14 +253,44 @@ inline ReverseRegSetIterator<RegImpl> AbstractRegSet<RegImpl>::rbegin() {

// Debugging support

template<typename R, typename... Rx>
inline constexpr bool different_registers(AbstractRegSet<R> allocated_regs, R first_register) {
return ! allocated_regs.contains(first_register);
}

template<typename R, typename... Rx>
inline constexpr bool different_registers(AbstractRegSet<R> allocated_regs, R first_register, Rx... more_registers) {
if (allocated_regs.contains(first_register))
return false;
return different_registers(allocated_regs + first_register, more_registers...);
}

template<typename R, typename... Rx>
inline constexpr bool different_registers(R first_register, Rx... more_registers) {
return different_registers(AbstractRegSet<R>(first_register), more_registers...);
}

template<typename R, typename... Rx>
inline constexpr bool different_registers(R reg1, R reg2) {
return reg1 != reg2;
}

template<typename R, typename... Rx>
inline constexpr bool different_registers(R reg1, R reg2, R reg3) {
return reg1 != reg2 && reg2 != reg3 && reg1 != reg3;
}

template<typename R, typename... Rx>
inline void assert_different_registers(R first_register, Rx... more_registers) {
#ifdef ASSERT
const R regs[] = { first_register, more_registers... };
// Verify there are no equal entries.
for (size_t i = 0; i < ARRAY_SIZE(regs) - 1; ++i) {
for (size_t j = i + 1; j < ARRAY_SIZE(regs); ++j) {
assert(regs[i] != regs[j], "Multiple uses of register: %s", regs[i]->name());
if (! different_registers(first_register, more_registers...)) {
const R regs[] = { first_register, more_registers... };
// Find a duplicate entry.
for (size_t i = 0; i < ARRAY_SIZE(regs) - 1; ++i) {
for (size_t j = i + 1; j < ARRAY_SIZE(regs); ++j) {
assert(! regs[i]->is_valid() || regs[i] != regs[j],
"Multiple uses of register: %s", regs[i]->name());
}
}
}
#endif
Expand Down

0 comments on commit 8258852

Please sign in to comment.