diff options
| author | Mattias Andrée <maandree@kth.se> | 2016-05-07 03:02:56 +0200 |
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2016-05-07 03:02:56 +0200 |
| commit | fdc75a358e4c20116640c08f4e8ce7a09dc3cebd (patch) | |
| tree | ca67767e06b0dd9d734dc027bb02a4a47681241e /zahl/memory.h | |
| parent | Make zdiv and zmod (calls zdivmod) inline (diff) | |
| download | libzahl-fdc75a358e4c20116640c08f4e8ce7a09dc3cebd.tar.gz libzahl-fdc75a358e4c20116640c08f4e8ce7a09dc3cebd.tar.bz2 libzahl-fdc75a358e4c20116640c08f4e8ce7a09dc3cebd.tar.xz | |
Optimisations
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'zahl/memory.h')
| -rw-r--r-- | zahl/memory.h | 133 |
1 files changed, 133 insertions, 0 deletions
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); +} |
