aboutsummaryrefslogtreecommitdiffstats
path: root/src/zxor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/zxor.c')
-rw-r--r--src/zxor.c48
1 files changed, 32 insertions, 16 deletions
diff --git a/src/zxor.c b/src/zxor.c
index f973774..601a947 100644
--- a/src/zxor.c
+++ b/src/zxor.c
@@ -2,18 +2,33 @@
#include "internals.h"
-static inline void
-zxor_impl(zahl_char_t *restrict a, const zahl_char_t *restrict b, size_t n)
+O2 static inline void
+zxor_impl_3(register zahl_char_t *restrict a,
+ register const zahl_char_t *restrict b, size_t n)
{
size_t i;
for (i = 0; i < n; i++)
a[i] ^= b[i];
}
+static inline void
+zxor_impl_5(register zahl_char_t *restrict a,
+ register const zahl_char_t *restrict b, size_t n,
+ register const zahl_char_t *restrict c, size_t m)
+{
+ size_t i;
+ for (i = 0; i < n; i++)
+ a[i] = b[i] ^ c[i];
+ for (; i < m; i++)
+ a[i] = c[i];
+}
+
void
zxor(z_t a, z_t b, z_t c)
{
- size_t n, m;
+ size_t n, m, bn, cn;
+ const zahl_char_t *restrict bc;
+ const zahl_char_t *restrict cc;
if (unlikely(zzero(b))) {
SET(a, c);
@@ -23,25 +38,26 @@ zxor(z_t a, z_t b, z_t c)
return;
}
- m = MAX(b->used, c->used);
- n = b->used + c->used - m;
+ bn = b->used;
+ bc = b->chars;
+ cn = c->used;
+ cc = c->chars;
+ MIN_MAX_1(n, m, bn, cn);
ENSURE_SIZE(a, m);
if (a == b) {
- if (a->used < c->used)
- zmemcpy(a->chars + n, c->chars + n, m - n);
- zxor_impl(a->chars, c->chars, n);
+ zxor_impl_3(a->chars, cc, n);
+ if (a->used < cn)
+ zmemcpy_range(a->chars, cc, n, m);
} else if (unlikely(a == c)) {
- if (a->used < b->used)
- zmemcpy(a->chars + n, b->chars + n, m - n);
- zxor_impl(a->chars, b->chars, n);
- } else if (m == b->used) {
- zmemcpy(a->chars, b->chars, m);
- zxor_impl(a->chars, c->chars, n);
+ zxor_impl_3(a->chars, bc, n);
+ if (a->used < bn)
+ zmemcpy_range(a->chars, bc, n, m);
+ } else if (m == bn) {
+ zxor_impl_5(a->chars, cc, n, bc, m);
} else {
- zmemcpy(a->chars, c->chars, m);
- zxor_impl(a->chars, b->chars, n);
+ zxor_impl_5(a->chars, bc, n, cc, m);
}
a->used = m;