| | #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(); |
| | } |