diff options
author | Xi Ruoyao <xry111@xry111.site> | 2024-12-13 15:46:00 +0800 |
---|---|---|
committer | Xi Ruoyao <xry111@xry111.site> | 2024-12-18 16:48:34 +0800 |
commit | c5424185b0c3652086efc914fa1e0c83365f6072 (patch) | |
tree | 8f82c8db21089a194cc8f8d8585aea86a11839a9 | |
parent | 80491b0493ac1e2b0cdbdfc3eab8c5c5a390d77c (diff) | |
download | gcc-c5424185b0c3652086efc914fa1e0c83365f6072.zip gcc-c5424185b0c3652086efc914fa1e0c83365f6072.tar.gz gcc-c5424185b0c3652086efc914fa1e0c83365f6072.tar.bz2 |
LoongArch: Add crc tests
gcc/testsuite/ChangeLog:
* g++.target/loongarch/crc.C: New test.
* g++.target/loongarch/crc-scan.C: New test.
-rw-r--r-- | gcc/testsuite/g++.target/loongarch/crc-scan.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.target/loongarch/crc.C | 120 |
2 files changed, 133 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.target/loongarch/crc-scan.C b/gcc/testsuite/g++.target/loongarch/crc-scan.C new file mode 100644 index 0000000..971580f --- /dev/null +++ b/gcc/testsuite/g++.target/loongarch/crc-scan.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64" } */ + +#include "crc.C" + +/* { dg-final { scan-assembler-times "crc\\.w\\.b\\.w" 2 } } */ +/* { dg-final { scan-assembler-times "crc\\.w\\.h\\.w" 2 } } */ +/* { dg-final { scan-assembler-times "crc\\.w\\.w\\.w" 2 } } */ +/* { dg-final { scan-assembler-times "crcc\\.w\\.b\\.w" 2 } } */ +/* { dg-final { scan-assembler-times "crcc\\.w\\.h\\.w" 2 } } */ +/* { dg-final { scan-assembler-times "crcc\\.w\\.w\\.w" 2 } } */ +/* { dg-final { scan-assembler-not "crc\\.w\\.\[bhw\]\\.w\t\\\$r\[0-9\]+,\\\$r0" } } */ +/* { dg-final { scan-assembler-not "crcc\\.w\\.\[bhw\]\\.w\t\\\$r\[0-9\]+,\\\$r0" } } */ diff --git a/gcc/testsuite/g++.target/loongarch/crc.C b/gcc/testsuite/g++.target/loongarch/crc.C new file mode 100644 index 0000000..16df4a1 --- /dev/null +++ b/gcc/testsuite/g++.target/loongarch/crc.C @@ -0,0 +1,120 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +typedef __UINT8_TYPE__ uint8_t; +typedef __UINT16_TYPE__ uint16_t; +typedef __UINT32_TYPE__ uint32_t; +typedef __UINT64_TYPE__ uint64_t; +typedef __SIZE_TYPE__ size_t; + +template <class T, uint32_t poly> +__attribute__ ((always_inline)) inline uint32_t +crc32_impl (const T *data, size_t len) +{ + uint32_t ret = 0xffffffffu; + for (size_t k = 0; k < len; k++) + { + ret ^= data[k]; + for (int i = 0; i < 8 * sizeof (T); i++) + if (ret & 1) + ret = (ret >> 1) ^ poly; + else + ret >>= 1; + } + return ret; +} + +template <class T, uint32_t poly> +__attribute__ ((noipa, optimize (0))) uint32_t +crc32_ref (const T *data, size_t len) +{ + return crc32_impl<T, poly> (data, len); +} + +template <class T, uint32_t poly> +__attribute__ ((noipa)) uint32_t +crc32_opt (const T *data, size_t len) +{ + return crc32_impl<T, poly> (data, len); +} + +template <class T, uint32_t poly> +__attribute__ ((noipa)) uint32_t +crc32_alt (const T *data, size_t len) +{ + uint32_t ret = 0xffffffffu; + for (size_t k = 0; k < len; k++) + { + T x = data[k]; + for (int i = 0; i < 8 * sizeof (T); i++) + { + if ((ret & 1) ^ (x & 1)) + ret = (ret >> 1) ^ poly; + else + ret >>= 1; + x >>= 1; + } + } + return ret; +} + +union test_data_t +{ + uint8_t u8[1024]; + uint16_t u16[512]; + uint32_t u32[256]; + + operator const uint8_t * () const { return u8; } + operator const uint16_t * () const { return u16; } + operator const uint32_t * () const { return u32; } + + constexpr + test_data_t () + : u8{} + { + } +}; + +/* Generate test data at compile time with minstd_rand0 algorithm. */ +constexpr test_data_t +gen (uint64_t seed) +{ + uint64_t state = seed; + test_data_t ret; + for (int i = 0; i < sizeof (ret); i++) + { + state = state * 16807 % 2147483647; + ret.u8[i] = (uint8_t)state; + } + return ret; +} + +constexpr union test_data_t test_data = gen (0xdeadbeef); + +void +assert_eq (uint32_t x, uint32_t y) +{ + if (x != y) + __builtin_trap (); +} + +template <class T, uint32_t poly> +void +test_crc32 () +{ + constexpr size_t len = sizeof (test_data) / sizeof (T); + uint32_t ref = crc32_ref<T, poly> (test_data, len); + assert_eq (ref, crc32_opt<T, poly> (test_data, len)); + assert_eq (ref, crc32_alt<T, poly> (test_data, len)); +} + +int +main (void) +{ + test_crc32<uint32_t, 0xEDB88320u> (); + test_crc32<uint16_t, 0xEDB88320u> (); + test_crc32<uint8_t, 0xEDB88320u> (); + test_crc32<uint32_t, 0x82F63B78u> (); + test_crc32<uint16_t, 0x82F63B78u> (); + test_crc32<uint8_t, 0x82F63B78u> (); +} |