@@ -248,10 +248,68 @@ static KANZI_ALWAYS_INLINE uint64 knz_bswap64(uint64 x) {
248248
249249#endif
250250
251+ static KANZI_ALWAYS_INLINE void memXor8 (byte* dst, const byte* x, const byte* y)
252+ {
253+ #if !defined(NO_INTRINSICS) && (defined(__ARM_NEON) || defined(__aarch64__))
254+ vst1_u8 (reinterpret_cast <uint8_t *>(dst),
255+ veor_u8 (vld1_u8 (reinterpret_cast <const uint8_t *>(x)),
256+ vld1_u8 (reinterpret_cast <const uint8_t *>(y))));
257+ #elif !defined(NO_INTRINSICS) && defined(__AVX512F__)
258+ const __mmask8 mask = 0x01 ;
259+ const __m512i a = _mm512_maskz_loadu_epi64 (mask, x);
260+ const __m512i b = _mm512_maskz_loadu_epi64 (mask, y);
261+ _mm512_mask_storeu_epi64 (dst, mask, _mm512_xor_si512 (a, b));
262+ #elif !defined(NO_INTRINSICS) && defined(__AVX2__)
263+ const __m256i mask = _mm256_set_epi64x (0 , 0 , 0 , -1 );
264+ const __m256i a = _mm256_maskload_epi64 (reinterpret_cast <const long long *>(x), mask);
265+ const __m256i b = _mm256_maskload_epi64 (reinterpret_cast <const long long *>(y), mask);
266+ _mm256_maskstore_epi64 (reinterpret_cast <long long *>(dst), mask, _mm256_xor_si256 (a, b));
267+ #elif !defined(NO_INTRINSICS) && defined(__SSE2__)
268+ const __m128i a = _mm_loadl_epi64 (reinterpret_cast <const __m128i*>(x));
269+ const __m128i b = _mm_loadl_epi64 (reinterpret_cast <const __m128i*>(y));
270+ _mm_storel_epi64 (reinterpret_cast <__m128i*>(dst), _mm_xor_si128 (a, b));
271+ #else
272+ uint64 a;
273+ uint64 b;
274+ memcpy (&a, x, sizeof (uint64));
275+ memcpy (&b, y, sizeof (uint64));
276+ a ^= b;
277+ memcpy (dst, &a, sizeof (uint64));
278+ #endif
279+ }
280+
281+ static KANZI_ALWAYS_INLINE void memXor16 (byte* dst, const byte* x, const byte* y)
282+ {
283+ #if !defined(NO_INTRINSICS) && (defined(__ARM_NEON) || defined(__aarch64__))
284+ vst1q_u8 (reinterpret_cast <uint8_t *>(dst),
285+ veorq_u8 (vld1q_u8 (reinterpret_cast <const uint8_t *>(x)),
286+ vld1q_u8 (reinterpret_cast <const uint8_t *>(y))));
287+ #elif !defined(NO_INTRINSICS) && defined(__AVX512F__)
288+ const __mmask8 mask = 0x03 ;
289+ const __m512i a = _mm512_maskz_loadu_epi64 (mask, x);
290+ const __m512i b = _mm512_maskz_loadu_epi64 (mask, y);
291+ _mm512_mask_storeu_epi64 (dst, mask, _mm512_xor_si512 (a, b));
292+ #elif !defined(NO_INTRINSICS) && defined(__AVX2__)
293+ const __m256i mask = _mm256_set_epi64x (0 , 0 , -1 , -1 );
294+ const __m256i a = _mm256_maskload_epi64 (reinterpret_cast <const long long *>(x), mask);
295+ const __m256i b = _mm256_maskload_epi64 (reinterpret_cast <const long long *>(y), mask);
296+ _mm256_maskstore_epi64 (reinterpret_cast <long long *>(dst), mask, _mm256_xor_si256 (a, b));
297+ #elif !defined(NO_INTRINSICS) && defined(__SSE2__)
298+ const __m128i a = _mm_loadu_si128 (reinterpret_cast <const __m128i*>(x));
299+ const __m128i b = _mm_loadu_si128 (reinterpret_cast <const __m128i*>(y));
300+ _mm_storeu_si128 (reinterpret_cast <__m128i*>(dst), _mm_xor_si128 (a, b));
301+ #else
302+ memXor8 (dst, x, y);
303+ memXor8 (dst + 8 , x + 8 , y + 8 );
304+ #endif
305+ }
306+
251307#define KANZI_MEM_EQ4 (x, y ) (::kanzi::memEq4((x), (y)))
252308#define KANZI_MEM_EQ8 (x, y ) (::kanzi::memEq8((x), (y)))
253309#define KANZI_MEM_CP8 (dst, src ) (::kanzi::memCp8((dst), (src)))
254310#define KANZI_MEM_CP16 (dst, src ) (::kanzi::memCp16((dst), (src)))
311+ #define KANZI_MEM_XOR8 (dst, x, y ) (::kanzi::memXor8((dst), (x), (y)))
312+ #define KANZI_MEM_XOR16 (dst, x, y ) (::kanzi::memXor16((dst), (x), (y)))
255313
256314// Detect host endianness
257315
0 commit comments