-
-
Save dougallj/6a5594d0040c6f1aa476cb8ca642dfa5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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