summaryrefslogtreecommitdiffstats
path: root/src/kmk/inlined_memchr.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/kmk/inlined_memchr.h')
-rw-r--r--src/kmk/inlined_memchr.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/kmk/inlined_memchr.h b/src/kmk/inlined_memchr.h
new file mode 100644
index 0000000..9666635
--- /dev/null
+++ b/src/kmk/inlined_memchr.h
@@ -0,0 +1,162 @@
+#define _GNU_SOURCE 1
+#include <string.h>
+
+#ifdef _MSC_VER
+_inline void *
+#else
+static __inline__ void *
+#endif
+my_inline_memchr(const void *pv, int ch, register size_t cb)
+{
+ register const unsigned int uch = (unsigned)ch;
+ register const unsigned char *pb = (const unsigned char *)pv;
+#if 0 /* 8-byte loop unroll */
+ while (cb >= 8)
+ {
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ if (pb[1] == uch)
+ return (unsigned char *)pb + 1;
+ if (pb[2] == uch)
+ return (unsigned char *)pb + 2;
+ if (pb[3] == uch)
+ return (unsigned char *)pb + 3;
+ if (pb[4] == uch)
+ return (unsigned char *)pb + 4;
+ if (pb[5] == uch)
+ return (unsigned char *)pb + 5;
+ if (pb[6] == uch)
+ return (unsigned char *)pb + 6;
+ if (pb[7] == uch)
+ return (unsigned char *)pb + 7;
+ cb -= 8;
+ pb += 8;
+ }
+ switch (cb & 7)
+ {
+ case 0:
+ break;
+ case 1:
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ break;
+ case 2:
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ if (pb[1] == uch)
+ return (unsigned char *)pb + 1;
+ break;
+ case 3:
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ if (pb[1] == uch)
+ return (unsigned char *)pb + 1;
+ if (pb[2] == uch)
+ return (unsigned char *)pb + 2;
+ break;
+ case 4:
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ if (pb[1] == uch)
+ return (unsigned char *)pb + 1;
+ if (pb[2] == uch)
+ return (unsigned char *)pb + 2;
+ if (pb[3] == uch)
+ return (unsigned char *)pb + 3;
+ break;
+ case 5:
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ if (pb[1] == uch)
+ return (unsigned char *)pb + 1;
+ if (pb[2] == uch)
+ return (unsigned char *)pb + 2;
+ if (pb[3] == uch)
+ return (unsigned char *)pb + 3;
+ if (pb[4] == uch)
+ return (unsigned char *)pb + 4;
+ break;
+ case 6:
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ if (pb[1] == uch)
+ return (unsigned char *)pb + 1;
+ if (pb[2] == uch)
+ return (unsigned char *)pb + 2;
+ if (pb[3] == uch)
+ return (unsigned char *)pb + 3;
+ if (pb[4] == uch)
+ return (unsigned char *)pb + 4;
+ if (pb[5] == uch)
+ return (unsigned char *)pb + 5;
+ break;
+ case 7:
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ if (pb[1] == uch)
+ return (unsigned char *)pb + 1;
+ if (pb[2] == uch)
+ return (unsigned char *)pb + 2;
+ if (pb[3] == uch)
+ return (unsigned char *)pb + 3;
+ if (pb[4] == uch)
+ return (unsigned char *)pb + 4;
+ if (pb[5] == uch)
+ return (unsigned char *)pb + 5;
+ if (pb[6] == uch)
+ return (unsigned char *)pb + 6;
+ break;
+ }
+
+#elif 1 /* 4 byte loop unroll */
+ while (cb >= 4)
+ {
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ if (pb[1] == uch)
+ return (unsigned char *)pb + 1;
+ if (pb[2] == uch)
+ return (unsigned char *)pb + 2;
+ if (pb[3] == uch)
+ return (unsigned char *)pb + 3;
+ cb -= 4;
+ pb += 4;
+ }
+ switch (cb & 3)
+ {
+ case 0:
+ break;
+ case 1:
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ break;
+ case 2:
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ if (pb[1] == uch)
+ return (unsigned char *)pb + 1;
+ break;
+ case 3:
+ if (*pb == uch)
+ return (unsigned char *)pb;
+ if (pb[1] == uch)
+ return (unsigned char *)pb + 1;
+ if (pb[2] == uch)
+ return (unsigned char *)pb + 2;
+ break;
+ }
+
+#else /* the basic loop */
+ while (cb > 0)
+ {
+ if (*pb == uch)
+ return (void *)pb;
+ cb--;
+ pb++;
+ }
+#endif
+ return 0;
+}
+
+#define memchr my_inline_memchr
+