mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 939157 - RotateLeft with shift of zero gives undefined behavior. r=Waldo
This commit is contained in:
parent
9e2d8fdf82
commit
24e061fa5a
@ -647,9 +647,13 @@ class Imm8 : public Operand2
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static datastore::Imm8mData EncodeImm(uint32_t imm) {
|
static datastore::Imm8mData EncodeImm(uint32_t imm) {
|
||||||
|
// RotateLeft below may not be called with a shift of zero.
|
||||||
|
if (imm <= 0xFF)
|
||||||
|
return datastore::Imm8mData(imm, 0);
|
||||||
|
|
||||||
// An encodable integer has a maximum of 8 contiguous set bits,
|
// An encodable integer has a maximum of 8 contiguous set bits,
|
||||||
// with an optional wrapped left rotation to even bit positions.
|
// with an optional wrapped left rotation to even bit positions.
|
||||||
for (int rot = 0; rot < 16; rot++) {
|
for (int rot = 1; rot < 16; rot++) {
|
||||||
uint32_t rotimm = mozilla::RotateLeft(imm, rot*2);
|
uint32_t rotimm = mozilla::RotateLeft(imm, rot*2);
|
||||||
if (rotimm <= 0xFF)
|
if (rotimm <= 0xFF)
|
||||||
return datastore::Imm8mData(rotimm, rot);
|
return datastore::Imm8mData(rotimm, rot);
|
||||||
|
@ -484,6 +484,11 @@ inline T
|
|||||||
RotateLeft(const T aValue, uint_fast8_t aShift)
|
RotateLeft(const T aValue, uint_fast8_t aShift)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!");
|
MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!");
|
||||||
|
MOZ_ASSERT(aShift > 0,
|
||||||
|
"Rotation by value length is undefined behavior, but compilers "
|
||||||
|
"do not currently fold a test into the rotate instruction. "
|
||||||
|
"Please remove this restriction when compilers optimize the "
|
||||||
|
"zero case (http://blog.regehr.org/archives/1063).");
|
||||||
static_assert(IsUnsigned<T>::value, "Rotates require unsigned values");
|
static_assert(IsUnsigned<T>::value, "Rotates require unsigned values");
|
||||||
return (aValue << aShift) | (aValue >> (sizeof(T) * CHAR_BIT - aShift));
|
return (aValue << aShift) | (aValue >> (sizeof(T) * CHAR_BIT - aShift));
|
||||||
}
|
}
|
||||||
@ -496,6 +501,11 @@ inline T
|
|||||||
RotateRight(const T aValue, uint_fast8_t aShift)
|
RotateRight(const T aValue, uint_fast8_t aShift)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!");
|
MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!");
|
||||||
|
MOZ_ASSERT(aShift > 0,
|
||||||
|
"Rotation by value length is undefined behavior, but compilers "
|
||||||
|
"do not currently fold a test into the rotate instruction. "
|
||||||
|
"Please remove this restriction when compilers optimize the "
|
||||||
|
"zero case (http://blog.regehr.org/archives/1063).");
|
||||||
static_assert(IsUnsigned<T>::value, "Rotates require unsigned values");
|
static_assert(IsUnsigned<T>::value, "Rotates require unsigned values");
|
||||||
return (aValue >> aShift) | (aValue << (sizeof(T) * CHAR_BIT - aShift));
|
return (aValue >> aShift) | (aValue << (sizeof(T) * CHAR_BIT - aShift));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user