@@ -43,12 +43,42 @@ typedef uint32 pg_crc32c;
43
43
44
44
#if defined(USE_SSE42_CRC32C )
45
45
/* Use Intel SSE4.2 instructions. */
46
+
47
+ #include <nmmintrin.h>
48
+
46
49
#define COMP_CRC32C (crc , data , len ) \
47
- ((crc) = pg_comp_crc32c_sse42 ((crc), (data), (len)))
50
+ ((crc) = pg_comp_crc32c_dispatch ((crc), (data), (len)))
48
51
#define FIN_CRC32C (crc ) ((crc) ^= 0xFFFFFFFF)
49
52
50
53
extern pg_crc32c pg_comp_crc32c_sse42 (pg_crc32c crc , const void * data , size_t len );
51
54
55
+ pg_attribute_no_sanitize_alignment ()
56
+ static inline
57
+ pg_crc32c
58
+ pg_comp_crc32c_dispatch (pg_crc32c crc , const void * data , size_t len )
59
+ {
60
+ if (__builtin_constant_p (len ) && len < 32 )
61
+ {
62
+ const unsigned char * p = data ;
63
+
64
+ /*
65
+ * For small constant inputs, inline the computation to avoid a
66
+ * function call and allow the compiler to unroll loops.
67
+ */
68
+ #if SIZEOF_VOID_P >= 8
69
+ for (; len >= 8 ; p += 8 , len -= 8 )
70
+ crc = _mm_crc32_u64 (crc , * (const uint64 * ) p );
71
+ #endif
72
+ for (; len >= 4 ; p += 4 , len -= 4 )
73
+ crc = _mm_crc32_u32 (crc , * (const uint32 * ) p );
74
+ for (; len > 0 ; -- len )
75
+ crc = _mm_crc32_u8 (crc , * p ++ );
76
+ return crc ;
77
+ }
78
+ else
79
+ return pg_comp_crc32c_sse42 (crc , data , len );
80
+ }
81
+
52
82
#elif defined(USE_ARMV8_CRC32C )
53
83
/* Use ARMv8 CRC Extension instructions. */
54
84
0 commit comments