/* This file is part of limb https://lila.oss/limb
* Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */
/* SPDX-License-Identifier: GPL-2.0-only */
#include <string.h>
#include <limb/memxor.h>
static void
xor8(void *dst_, const void *src_, size_t len)
{
u8 *dst = dst_;
const u8 *src = src_;
while (len--) {
*dst ^= *src;
++dst;
++src;
}
}
static void
xor64(void *dst_, const void *src_, size_t len)
{
u64 *dst = dst_;
const u64 *src = src_;
size_t n = len / sizeof(u64);
len -= n * sizeof(u64);
while (n >= 4) {
dst[0] ^= src[0];
dst[1] ^= src[1];
dst[2] ^= src[2];
dst[3] ^= src[3];
dst += 4;
src += 4;
n -= 4;
}
while (n >= 1) {
*dst ^= *src;
++dst;
++src;
--n;
}
xor8(dst, src, len);
}
void
memxor(void *dst_, const void *src_, size_t len)
{
u8 *dst = dst_;
const u8 *src = src_;
size_t off = ALIGN_OFFSET(dst);
if (off) {
off = sizeof(word_t) - off;
if (off > len)
off = len;
xor8(dst, src, off);
dst += off;
src += off;
len -= off;
}
off = ALIGN_OFFSET(src);
if (off) {
u8 buf[8092];
size_t blen = sizeof(buf);
while (len) {
if (blen > len) blen = len;
memcpy(buf, src, blen);
xor64(dst, buf, blen);
dst += blen;
src += blen;
len -= blen;
}
} else {
xor64(dst, src, len);
}
}