-// Copyright 2013, ARM Limited
+// Copyright 2015, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "utils.h"
-#include <stdio.h>
+#include "compiler-intrinsics.h"
namespace vixl {
-uint32_t float_to_rawbits(float value) {
- uint32_t bits = 0;
- memcpy(&bits, &value, 4);
- return bits;
-}
-
-
-uint64_t double_to_rawbits(double value) {
- uint64_t bits = 0;
- memcpy(&bits, &value, 8);
- return bits;
-}
-
-
-float rawbits_to_float(uint32_t bits) {
- float value = 0.0;
- memcpy(&value, &bits, 4);
- return value;
-}
-
-
-double rawbits_to_double(uint64_t bits) {
- double value = 0.0;
- memcpy(&value, &bits, 8);
- return value;
-}
-
-int CountLeadingZeros(uint64_t value, int width) {
- VIXL_ASSERT((width == 32) || (width == 64));
- int count = 0;
- uint64_t bit_test = UINT64_C(1) << (width - 1);
- while ((count < width) && ((bit_test & value) == 0)) {
- count++;
- bit_test >>= 1;
- }
- return count;
-}
-
-
-int CountLeadingSignBits(int64_t value, int width) {
- VIXL_ASSERT((width == 32) || (width == 64));
+int CountLeadingSignBitsFallBack(int64_t value, int width) {
+ VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
if (value >= 0) {
return CountLeadingZeros(value, width) - 1;
} else {
}
-int CountTrailingZeros(uint64_t value, int width) {
- VIXL_ASSERT((width == 32) || (width == 64));
+int CountLeadingZerosFallBack(uint64_t value, int width) {
+ VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
+ if (value == 0) {
+ return width;
+ }
int count = 0;
- while ((count < width) && (((value >> count) & 1) == 0)) {
- count++;
+ value = value << (64 - width);
+ if ((value & UINT64_C(0xffffffff00000000)) == 0) {
+ count += 32;
+ value = value << 32;
}
+ if ((value & UINT64_C(0xffff000000000000)) == 0) {
+ count += 16;
+ value = value << 16;
+ }
+ if ((value & UINT64_C(0xff00000000000000)) == 0) {
+ count += 8;
+ value = value << 8;
+ }
+ if ((value & UINT64_C(0xf000000000000000)) == 0) {
+ count += 4;
+ value = value << 4;
+ }
+ if ((value & UINT64_C(0xc000000000000000)) == 0) {
+ count += 2;
+ value = value << 2;
+ }
+ if ((value & UINT64_C(0x8000000000000000)) == 0) {
+ count += 1;
+ }
+ count += (value == 0);
return count;
}
-int CountSetBits(uint64_t value, int width) {
- // TODO: Other widths could be added here, as the implementation already
- // supports them.
- VIXL_ASSERT((width == 32) || (width == 64));
+int CountSetBitsFallBack(uint64_t value, int width) {
+ VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
// Mask out unused bits to ensure that they are not counted.
- value &= (UINT64_C(0xffffffffffffffff) >> (64-width));
+ value &= (UINT64_C(0xffffffffffffffff) >> (64 - width));
// Add up the set bits.
// The algorithm works by adding pairs of bit fields together iteratively,
value = ((value >> shift) & kMasks[i]) + (value & kMasks[i]);
}
- return value;
-}
-
-
-uint64_t LowestSetBit(uint64_t value) {
- return value & -value;
-}
-
-
-bool IsPowerOf2(int64_t value) {
- return (value != 0) && ((value & (value - 1)) == 0);
+ return static_cast<int>(value);
}
-unsigned CountClearHalfWords(uint64_t imm, unsigned reg_size) {
- VIXL_ASSERT((reg_size % 8) == 0);
+int CountTrailingZerosFallBack(uint64_t value, int width) {
+ VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
int count = 0;
- for (unsigned i = 0; i < (reg_size / 16); i++) {
- if ((imm & 0xffff) == 0) {
- count++;
- }
- imm >>= 16;
+ value = value << (64 - width);
+ if ((value & UINT64_C(0xffffffff)) == 0) {
+ count += 32;
+ value = value >> 32;
}
- return count;
+ if ((value & 0xffff) == 0) {
+ count += 16;
+ value = value >> 16;
+ }
+ if ((value & 0xff) == 0) {
+ count += 8;
+ value = value >> 8;
+ }
+ if ((value & 0xf) == 0) {
+ count += 4;
+ value = value >> 4;
+ }
+ if ((value & 0x3) == 0) {
+ count += 2;
+ value = value >> 2;
+ }
+ if ((value & 0x1) == 0) {
+ count += 1;
+ }
+ count += (value == 0);
+ return count - (64 - width);
}
+
} // namespace vixl