| #include "unity/unity.h" |
| #include "zlib.h" |
|
|
| #include <stdint.h> |
| #include <stdlib.h> |
|
|
| |
| #if defined(__x86_64__) || defined(__aarch64__) |
| #define TEST_W 8 |
| typedef unsigned long long test_word_t; |
| extern unsigned long long test_byte_swap(unsigned long long word); |
| #else |
| #define TEST_W 4 |
| typedef unsigned long test_word_t; |
| extern unsigned long test_byte_swap(unsigned long word); |
| #endif |
|
|
| |
| static test_word_t ref_swap(test_word_t v) { |
| test_word_t out = 0; |
| for (int i = 0; i < TEST_W; i++) { |
| unsigned int b = (unsigned int)((v >> (8 * i)) & (test_word_t)0xFF); |
| out |= ((test_word_t)b) << (8 * (TEST_W - 1 - i)); |
| } |
| return out; |
| } |
|
|
| void setUp(void) { |
| |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
| void test_byte_swap_zero(void) { |
| test_word_t in = (test_word_t)0; |
| test_word_t out = test_byte_swap(in); |
| TEST_ASSERT_EQUAL_HEX64((uint64_t)0, (uint64_t)out); |
| } |
|
|
| |
| void test_byte_swap_known_pattern(void) { |
| #if TEST_W == 4 |
| test_word_t in = (test_word_t)0x01234567UL; |
| test_word_t expected = (test_word_t)0x67452301UL; |
| test_word_t out = test_byte_swap(in); |
| TEST_ASSERT_EQUAL_HEX32((uint32_t)expected, (uint32_t)out); |
| #else |
| test_word_t in = (test_word_t)0x0123456789ABCDEFULL; |
| test_word_t expected = (test_word_t)0xEFCDAB8967452301ULL; |
| test_word_t out = test_byte_swap(in); |
| |
| TEST_ASSERT_EQUAL_HEX64((uint64_t)expected, (uint64_t)out); |
| #endif |
| } |
|
|
| |
| void test_byte_swap_all_bytes_same(void) { |
| #if TEST_W == 4 |
| test_word_t in1 = (test_word_t)0x01010101UL; |
| test_word_t in2 = (test_word_t)0xFFFFFFFFUL; |
| TEST_ASSERT_EQUAL_HEX32((uint32_t)in1, (uint32_t)test_byte_swap(in1)); |
| TEST_ASSERT_EQUAL_HEX32((uint32_t)in2, (uint32_t)test_byte_swap(in2)); |
| #else |
| test_word_t in1 = (test_word_t)0x0101010101010101ULL; |
| test_word_t in2 = (test_word_t)0xFFFFFFFFFFFFFFFFULL; |
| TEST_ASSERT_EQUAL_HEX64((uint64_t)in1, (uint64_t)test_byte_swap(in1)); |
| TEST_ASSERT_EQUAL_HEX64((uint64_t)in2, (uint64_t)test_byte_swap(in2)); |
| #endif |
| } |
|
|
| |
| void test_byte_swap_involution(void) { |
| |
| #if TEST_W == 4 |
| test_word_t samples[] = { |
| 0x00000000UL, 0x00000001UL, 0x80000000UL, 0x7FFFFFFFUL, |
| 0x01234567UL, 0x89ABCDEFUL, 0xA5A5A5A5UL, 0x5A5A5A5AUL |
| }; |
| size_t count = sizeof(samples) / sizeof(samples[0]); |
| for (size_t i = 0; i < count; i++) { |
| test_word_t x = samples[i]; |
| test_word_t y = test_byte_swap(test_byte_swap(x)); |
| TEST_ASSERT_EQUAL_HEX32((uint32_t)x, (uint32_t)y); |
| } |
| #else |
| test_word_t samples[] = { |
| 0x0000000000000000ULL, 0x0000000000000001ULL, |
| 0x8000000000000000ULL, 0x7FFFFFFFFFFFFFFFULL, |
| 0x0123456789ABCDEFULL, 0xFEDCBA9876543210ULL, |
| 0xA5A5A5A5A5A5A5A5ULL, 0x5A5A5A5A5A5A5A5AULL |
| }; |
| size_t count = sizeof(samples) / sizeof(samples[0]); |
| for (size_t i = 0; i < count; i++) { |
| test_word_t x = samples[i]; |
| test_word_t y = test_byte_swap(test_byte_swap(x)); |
| TEST_ASSERT_EQUAL_HEX64((uint64_t)x, (uint64_t)y); |
| } |
| #endif |
| } |
|
|
| |
| void test_byte_swap_single_byte_moves(void) { |
| for (int pos = 0; pos < TEST_W; pos++) { |
| test_word_t in = 0; |
| |
| in |= ((test_word_t)0xAA) << (8 * pos); |
| test_word_t out = test_byte_swap(in); |
| test_word_t expected = ((test_word_t)0xAA) << (8 * (TEST_W - 1 - pos)); |
| #if TEST_W == 4 |
| TEST_ASSERT_EQUAL_HEX32((uint32_t)expected, (uint32_t)out); |
| #else |
| TEST_ASSERT_EQUAL_HEX64((uint64_t)expected, (uint64_t)out); |
| #endif |
| } |
| } |
|
|
| |
| void test_byte_swap_palindromic_bytes(void) { |
| #if TEST_W == 4 |
| |
| test_word_t in = ((test_word_t)0x12 << 24) | |
| ((test_word_t)0x34 << 16) | |
| ((test_word_t)0x34 << 8) | |
| ((test_word_t)0x12); |
| test_word_t out = test_byte_swap(in); |
| TEST_ASSERT_EQUAL_HEX32((uint32_t)in, (uint32_t)out); |
| #else |
| |
| test_word_t in = ((test_word_t)0x01ULL << 56) | |
| ((test_word_t)0x23ULL << 48) | |
| ((test_word_t)0x45ULL << 40) | |
| ((test_word_t)0x67ULL << 32) | |
| ((test_word_t)0x67ULL << 24) | |
| ((test_word_t)0x45ULL << 16) | |
| ((test_word_t)0x23ULL << 8) | |
| ((test_word_t)0x01ULL); |
| test_word_t out = test_byte_swap(in); |
| TEST_ASSERT_EQUAL_HEX64((uint64_t)in, (uint64_t)out); |
| #endif |
| } |
|
|
| |
| void test_byte_swap_against_reference(void) { |
| |
| for (unsigned seed = 0; seed < 8; seed++) { |
| test_word_t in = 0; |
| for (int i = 0; i < TEST_W; i++) { |
| test_word_t b = (test_word_t)((seed + i * 37) & 0xFF); |
| in |= b << (8 * i); |
| } |
| test_word_t expected = ref_swap(in); |
| test_word_t out = test_byte_swap(in); |
| #if TEST_W == 4 |
| TEST_ASSERT_EQUAL_HEX32((uint32_t)expected, (uint32_t)out); |
| #else |
| TEST_ASSERT_EQUAL_HEX64((uint64_t)expected, (uint64_t)out); |
| #endif |
| } |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_byte_swap_zero); |
| RUN_TEST(test_byte_swap_known_pattern); |
| RUN_TEST(test_byte_swap_all_bytes_same); |
| RUN_TEST(test_byte_swap_involution); |
| RUN_TEST(test_byte_swap_single_byte_moves); |
| RUN_TEST(test_byte_swap_palindromic_bytes); |
| RUN_TEST(test_byte_swap_against_reference); |
| return UNITY_END(); |
| } |