summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2017-06-28 01:05:46 +0200
committerRichard Braun <rbraun@sceen.net>2017-06-28 01:06:11 +0200
commit66f04e038e510e27037c0c8a6673c5940c8b22f1 (patch)
treec97a6481f0fecb4e1c0658b7bbad5927810ef20f /arch
parent982e80f759f3174a9b91bbfa08221c2a11146417 (diff)
x86/string: implement assembly versions of strncmp and strchr
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/machine/string.c48
-rw-r--r--arch/x86/machine/string.h2
2 files changed, 50 insertions, 0 deletions
diff --git a/arch/x86/machine/string.c b/arch/x86/machine/string.c
index aa8795c8..e4f7f0c9 100644
--- a/arch/x86/machine/string.c
+++ b/arch/x86/machine/string.c
@@ -18,6 +18,7 @@
#include <stddef.h>
#include <string.h>
+#include <kern/macros.h>
#include <machine/string.h>
#ifdef STRING_ARCH_MEMCPY
@@ -145,3 +146,50 @@ strcmp(const char *s1, const char *s2)
return (int)c1 - (int)c2;
}
#endif /* STRING_ARCH_STRCMP */
+
+#ifdef STRING_ARCH_STRNCMP
+int
+strncmp(const char *s1, const char *s2, size_t n)
+{
+ unsigned char c1, c2;
+
+ if (unlikely(n == 0)) {
+ return 0;
+ }
+
+ asm volatile("1:\n"
+ "lodsb\n"
+ "scasb\n"
+ "jne 1f\n"
+ "testb %%al, %%al\n"
+ "jz 1f\n"
+ "dec %2\n"
+ "jnz 1b\n"
+ "1:\n"
+ : "+D" (s1), "+S" (s2), "+c" (n)
+ : : "al", "memory");
+ c1 = *(((const unsigned char *)s1) - 1);
+ c2 = *(((const unsigned char *)s2) - 1);
+ return (int)c1 - (int)c2;
+}
+#endif /* STRING_ARCH_STRNCMP */
+
+#ifdef STRING_ARCH_STRCHR
+char *
+strchr(const char *s, int c)
+{
+ asm volatile("1:\n"
+ "lodsb\n"
+ "cmpb %%al, %1\n"
+ "je 1f\n"
+ "testb %%al, %%al\n"
+ "jnz 1b\n"
+ "mov $1, %0\n"
+ "1:\n"
+ "dec %0\n"
+ : "+S" (s)
+ : "c" ((char)c)
+ : "al", "memory");
+ return (char *)s;
+}
+#endif /* STRING_ARCH_STRCHR */
diff --git a/arch/x86/machine/string.h b/arch/x86/machine/string.h
index d57bb24e..6111ba10 100644
--- a/arch/x86/machine/string.h
+++ b/arch/x86/machine/string.h
@@ -28,5 +28,7 @@
#define STRING_ARCH_STRLEN
#define STRING_ARCH_STRCPY
#define STRING_ARCH_STRCMP
+#define STRING_ARCH_STRNCMP
+#define STRING_ARCH_STRCHR
#endif /* _X86_STRING_H */