90 lines
3.4 KiB
C++
90 lines
3.4 KiB
C++
#include <cruft/util/bitwise.hpp>
|
|
#include <cruft/util/std.hpp>
|
|
#include <cruft/util/tap.hpp>
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
static void
|
|
test_rotate (cruft::TAP::logger &tap)
|
|
{
|
|
tap.expect_eq (cruft::rotatel (uint8_t (0x0F), 0), 0x0Fu, "rotate-left u8");
|
|
tap.expect_eq (cruft::rotatel (uint8_t (0x0F), 4), 0xF0u, "rotate-left u8");
|
|
tap.expect_eq (cruft::rotatel (uint8_t (0xF0), 4), 0x0Fu, "rotate-left u8");
|
|
|
|
tap.expect_eq (cruft::rotater (uint8_t (0x0F), 0), 0x0Fu, "rotate-right u8");
|
|
tap.expect_eq (cruft::rotater (uint8_t (0x0F), 4), 0xF0u, "rotate-right u8");
|
|
tap.expect_eq (cruft::rotater (uint8_t (0xF0), 4), 0x0Fu, "rotate-right u8");
|
|
|
|
tap.expect_eq (cruft::rotatel (uint16_t (0xABCD), 0), 0xABCDu, "rotate-left u16");
|
|
tap.expect_eq (cruft::rotatel (uint16_t (0xABCD), 4), 0xBCDAu, "rotate-left u16");
|
|
tap.expect_eq (cruft::rotatel (uint16_t (0xABCD), 8), 0xCDABu, "rotate-left u16");
|
|
tap.expect_eq (cruft::rotatel (uint16_t (0xABCD), 12), 0xDABCu, "rotate-left u16");
|
|
|
|
tap.expect_eq (cruft::rotater (uint16_t (0xABCD), 0), 0xABCDu, "rotate-right u16");
|
|
tap.expect_eq (cruft::rotater (uint16_t (0xABCD), 4), 0xDABCu, "rotate-right u16");
|
|
tap.expect_eq (cruft::rotater (uint16_t (0xABCD), 8), 0xCDABu, "rotate-right u16");
|
|
tap.expect_eq (cruft::rotater (uint16_t (0xABCD), 12), 0xBCDAu, "rotate-right u16");
|
|
|
|
tap.expect_eq (cruft::rotatel (uint32_t (0x12345670), 12), 0x45670123u, "rotate-left u32");
|
|
tap.expect_eq (cruft::rotater (uint32_t (0x12345670), 12), 0x67012345u, "rotate-right u32");
|
|
|
|
tap.expect_eq (cruft::rotatel (uint64_t (0x1234567890ABCDEF), 12), 0x4567890ABCDEF123u, "rotate-left u64");
|
|
tap.expect_eq (cruft::rotater (uint64_t (0x1234567890ABCDEF), 12), 0xDEF1234567890ABCu, "rotate-right u64");
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
test_reverse (cruft::TAP::logger &tap)
|
|
{
|
|
size_t matches = 0;
|
|
for (unsigned i = 0; i < 256; ++i) {
|
|
auto first = cruft::reverse<uint8_t> (i);
|
|
auto last = cruft::reverse<uint8_t> (first);
|
|
if (last == i)
|
|
matches++;
|
|
}
|
|
|
|
tap.expect_eq (matches, 256u, "exhaustive 8 bit reverse");
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
test_bitfield (cruft::TAP::logger &tap)
|
|
{
|
|
union {
|
|
/// * lo is set to 1 and hi is set to 0 to establish bit ordering
|
|
/// * mid pattern tests behaviour across byte boundaries
|
|
u16 raw = 0b0111'0011'0000'0001;
|
|
// | |mid^---^ |
|
|
// highest^ | lowest^
|
|
// high^--^
|
|
cruft::bitfield<u16, 0,1> lowest;
|
|
cruft::bitfield<u16,15,1> highest;
|
|
cruft::bitfield<u16,12,4> high;
|
|
cruft::bitfield<u16, 6,4> mid;
|
|
};
|
|
|
|
tap.expect_eq (lowest, u16 { 0b1}, "bitfield lowest bit");
|
|
tap.expect_eq (highest, u16 { 0b0}, "bitfield highest bit");
|
|
tap.expect_eq (high, u16 {0b0111}, "bitfield high bits");
|
|
tap.expect_eq (mid, u16 {0b1100}, "bitfield byte boundary bits");
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int
|
|
main (int, char**)
|
|
{
|
|
cruft::TAP::logger tap;
|
|
|
|
test_rotate (tap);
|
|
test_reverse (tap);
|
|
test_bitfield (tap);
|
|
|
|
tap.expect_eq (cruft::ctz (0b11110000u), 4u, "count-trailing-zero trivial test");
|
|
|
|
return tap.status ();
|
|
}
|