From fdc75a358e4c20116640c08f4e8ce7a09dc3cebd Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 7 May 2016 03:02:56 +0200 Subject: Optimisations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- zahl/memory.h | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 zahl/memory.h (limited to 'zahl/memory.h') diff --git a/zahl/memory.h b/zahl/memory.h new file mode 100644 index 0000000..2eb2b68 --- /dev/null +++ b/zahl/memory.h @@ -0,0 +1,133 @@ +/* See LICENSE file for copyright and license details. */ + +#define LIBZAHL_MEM_CASES \ + LIBZAHL_X(20); \ + LIBZAHL_X(19); \ + LIBZAHL_X(18); \ + LIBZAHL_X(17); \ + LIBZAHL_X(16); \ + LIBZAHL_X(15); \ + LIBZAHL_X(14); \ + LIBZAHL_X(13); \ + LIBZAHL_X(12); \ + LIBZAHL_X(11); \ + LIBZAHL_X(10); \ + LIBZAHL_X( 9); \ + LIBZAHL_X( 8); \ + LIBZAHL_X( 7); \ + LIBZAHL_X( 6); \ + LIBZAHL_X( 5); \ + LIBZAHL_X( 4); \ + LIBZAHL_X( 3); \ + LIBZAHL_X( 2); \ + LIBZAHL_X( 1); \ + case 0: break; + + +#if defined(LIBZAHL_ISA_MISSING_INDIRECT_JUMP) +# define LIBZAHL_SMALL_INPUT_BEGIN(n) +# define LIBZAHL_SMALL_INPUT_END +#else +# define LIBZAHL_SMALL_INPUT_BEGIN(n) switch (n) { LIBZAHL_MEM_CASES default: +# define LIBZAHL_SMALL_INPUT_END break; } +#endif + + +ZAHL_INLINE void +libzahl_memcpy(register zahl_char_t *restrict d, register const zahl_char_t *restrict s, size_t n) +{ + size_t i; +#define LIBZAHL_X(I) case I: d[I - 1] = s[I - 1]; + LIBZAHL_SMALL_INPUT_BEGIN(n); + for (i = 0; i < n; i += 4) { + d[i + 0] = s[i + 0]; + d[i + 1] = s[i + 1]; + d[i + 2] = s[i + 2]; + d[i + 3] = s[i + 3]; + } + LIBZAHL_SMALL_INPUT_END; +#undef LIBZAHL_X +} + + +ZAHL_INLINE void +libzahl_memset(register zahl_char_t *a, register zahl_char_t v, size_t n) +{ + size_t i; + for (i = 0; i < n; i += 4) { + a[i + 0] = v; + a[i + 1] = v; + a[i + 2] = v; + a[i + 3] = v; + } +} + +ZAHL_INLINE void +libzahl_memset_precise(register zahl_char_t *a, register zahl_char_t v, size_t n) +{ + size_t i; + if (n <= 4) { + if (n >= 1) + a[0] = v; + if (n >= 2) + a[1] = v; + if (n >= 3) + a[2] = v; + if (n >= 4) + a[3] = v; + } else { + for (i = 0; (i += 4) <= n;) { + a[i - 1] = v; + a[i - 2] = v; + a[i - 3] = v; + a[i - 4] = v; + } + if (i > n) + for (i -= 4; i < n; i++) + a[i] = v; + } +} + + +ZAHL_INLINE void +libzahl_memmovef(register zahl_char_t *d, register const zahl_char_t *s, size_t n) +{ + if (n && n < 4) { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + } else { + size_t i; + for (i = 0; i < n; i += 4) { + d[i + 0] = s[i + 0]; + d[i + 1] = s[i + 1]; + d[i + 2] = s[i + 2]; + d[i + 3] = s[i + 3]; + } + } +} + +ZAHL_INLINE void +libzahl_memmoveb(register zahl_char_t *d, register const zahl_char_t *s, size_t n) +{ + ssize_t i; +#define LIBZAHL_X(I) case I: d[I - 1] = s[I - 1]; + LIBZAHL_SMALL_INPUT_BEGIN(n); + for (i = ((ssize_t)n + 3) & ~3; (i -= 4) >= 0;) { + d[i + 3] = s[i + 3]; + d[i + 2] = s[i + 2]; + d[i + 1] = s[i + 1]; + d[i + 0] = s[i + 0]; + } + LIBZAHL_SMALL_INPUT_END; +#undef LIBZAHL_X +} + +ZAHL_INLINE void +libzahl_memmove(register zahl_char_t *d, register const zahl_char_t *s, size_t n) +{ + if (d < s) + libzahl_memmovef(d, s, n); + else + libzahl_memmoveb(d, s, n); +} -- cgit v1.2.3-70-g09d2