Skip to content

Instantly share code, notes, and snippets.

@dougallj
Last active July 7, 2022 06:07
Show Gist options
  • Save dougallj/6a5594d0040c6f1aa476cb8ca642dfa5 to your computer and use it in GitHub Desktop.
Save dougallj/6a5594d0040c6f1aa476cb8ca642dfa5 to your computer and use it in GitHub Desktop.
int CountTrailingZeros(uint64_t value) {
return value ? Common::LeastSignificantSetBit(value) : 64;
}
constexpr LogicalImm(u64 value, u32 width)
{
constexpr int kWRegSizeInBits = 32;
if (width == kWRegSizeInBits)
{
// To handle 32-bit logical immediates, the very easiest thing is to repeat
// the input value twice to make a 64-bit word. The correct encoding of that
// as a logical immediate will also be the correct encoding of the 32-bit
// value.
value <<= kWRegSizeInBits;
value |= value >> kWRegSizeInBits;
}
if (value == 0 || ~value == 0) {
valid = false;
return;
}
const size_t rotation = CountTrailingZeros(value & (value + 1));
const u64 normalized = Common::RotateRight(value, rotation);
const size_t zeroes = Common::CountLeadingZeros(normalized);
const size_t ones = Common::LeastSignificantSetBit(~normalized);
const size_t size = zeroes + ones;
// Check the value is repeating, which also ensures that size is a
// power of two.
if (Common::RotateRight(value, size) != value) {
valid = false;
return;
}
r = static_cast<u8>(-rotation & (size - 1));
s = (-(size << 1) | (ones - 1)) & 0x3f;
n = (size >> 6);
valid = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment