]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Add sse2 accelerated function for lowercasing and copying a string
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 16 Jun 2021 13:39:06 +0000 (14:39 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 16 Jun 2021 13:39:06 +0000 (14:39 +0100)
src/libutil/str_util.c
src/libutil/str_util.h

index 1e92c8e54f505517dd8984c5bd61bc608f407ded..6b0cc3b6817c3b9bbb397841099f278278099746 100644 (file)
 #endif
 #include <math.h>
 
+#ifdef __x86_64__
+#include <immintrin.h>
+#endif
+
 #include "contrib/fastutf8/fastutf8.h"
 
 const guchar lc_map[256] = {
@@ -98,6 +102,44 @@ rspamd_str_lc (gchar *str, guint size)
        return size;
 }
 
+gsize
+rspamd_str_copy_lc (const gchar *src, gchar *dst, gsize size)
+{
+       gchar *d = dst;
+
+       /* Find aligned start */
+       while ((0xf & (uintptr_t)src) && size > 0) {
+               *d++ = lc_map[(guchar)*src++];
+               size --;
+       }
+
+       /* Aligned start in src */
+#ifdef __x86_64__
+       while (size >= 16) {
+               __m128i sv = _mm_load_si128((const __m128i*)src);
+               /* From A */
+               __m128i rangeshift = _mm_sub_epi8(sv, _mm_set1_epi8((char)('A'+128)));
+               /* To Z */
+               __m128i nomodify = _mm_cmpgt_epi8(rangeshift, _mm_set1_epi8(-128 + 25));
+               /* ^ ' ' */
+               __m128i flip  = _mm_andnot_si128(nomodify, _mm_set1_epi8(0x20));
+               __m128i uc = _mm_xor_si128(sv, flip);
+               _mm_storeu_si128((__m128i*)d, uc);
+               d += 16;
+               src += 16;
+               size -= 16;
+       }
+#endif
+
+       /* Leftover */
+       while (size > 0) {
+               *d++ = lc_map[(guchar)*src++];
+               size --;
+       }
+
+       return (d - dst);
+}
+
 gint
 rspamd_lc_cmp (const gchar *s, const gchar *d, gsize l)
 {
index cfa37848fa994426c347ea645cf699eee17b4e70..e5e4cfb7662fb7857d2bc5ffcd47fd7f706b8854 100644 (file)
@@ -43,6 +43,14 @@ gint rspamd_lc_cmp (const gchar *s, const gchar *d, gsize l);
  */
 guint rspamd_str_lc (gchar *str, guint size);
 
+/**
+ * Performs ascii copy & lowercase
+ * @param src
+ * @param size
+ * @return
+ */
+gsize rspamd_str_copy_lc (const gchar *src, gchar *dst, gsize size);
+
 /**
  * Convert string to lowercase in-place using utf (limited) conversion
  */