summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2016-08-16 18:34:38 +0200
committerRichard Braun <rbraun@sceen.net>2016-08-16 18:34:38 +0200
commite26f13d83a560684e1aa6b11b1a43f8764eaa032 (patch)
tree5002fd6a53dd53a6afab7811fb94d4fb979131cf
parent34cfd8b3111b8085f566a68d7b39b0b9e90193d4 (diff)
i386: import string functions from X15 and relicense to GPLv2+
* i386/Makefrag.am (libkernel_a_SOURCES): Add i386/i386/strings.c. * i386/i386/strings.c: New file.
-rw-r--r--i386/Makefrag.am1
-rw-r--r--i386/i386/strings.c150
2 files changed, 151 insertions, 0 deletions
diff --git a/i386/Makefrag.am b/i386/Makefrag.am
index c61a3f6f..90f20fb9 100644
--- a/i386/Makefrag.am
+++ b/i386/Makefrag.am
@@ -151,6 +151,7 @@ libkernel_a_SOURCES += \
i386/i386/setjmp.h \
i386/i386/spl.S \
i386/i386/spl.h \
+ i386/i386/strings.c \
i386/i386/task.h \
i386/i386/thread.h \
i386/i386/time_stamp.h \
diff --git a/i386/i386/strings.c b/i386/i386/strings.c
new file mode 100644
index 00000000..84a3bc16
--- /dev/null
+++ b/i386/i386/strings.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2014 Richard Braun.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+#define ARCH_STRING_MEMCPY
+#define ARCH_STRING_MEMMOVE
+#define ARCH_STRING_MEMSET
+#define ARCH_STRING_MEMCMP
+
+#ifdef ARCH_STRING_MEMCPY
+void *
+memcpy(void *dest, const void *src, size_t n)
+{
+ void *orig_dest;
+
+ orig_dest = dest;
+ asm volatile("rep movsb"
+ : "+D" (dest), "+S" (src), "+c" (n)
+ : : "memory");
+ return orig_dest;
+}
+#endif /* ARCH_STRING_MEMCPY */
+
+#ifdef ARCH_STRING_MEMMOVE
+void *
+memmove(void *dest, const void *src, size_t n)
+{
+ void *orig_dest;
+
+ orig_dest = dest;
+
+ if (dest <= src)
+ asm volatile("rep movsb"
+ : "+D" (dest), "+S" (src), "+c" (n)
+ : : "memory");
+ else {
+ dest += n - 1;
+ src += n - 1;
+ asm volatile("std; rep movsb; cld"
+ : "+D" (dest), "+S" (src), "+c" (n)
+ : : "memory");
+ }
+
+ return orig_dest;
+}
+#endif /* ARCH_STRING_MEMMOVE */
+
+#ifdef ARCH_STRING_MEMSET
+void *
+memset(void *s, int c, size_t n)
+{
+ void *orig_s;
+
+ orig_s = s;
+ asm volatile("rep stosb"
+ : "+D" (s), "+c" (n)
+ : "a" (c)
+ : "memory");
+ return orig_s;
+}
+#endif /* ARCH_STRING_MEMSET */
+
+#ifdef ARCH_STRING_MEMCMP
+int
+memcmp(const void *s1, const void *s2, size_t n)
+{
+ unsigned char c1, c2;
+
+ if (n == 0)
+ return 0;
+
+ asm volatile("repe cmpsb"
+ : "+D" (s1), "+S" (s2), "+c" (n)
+ : : "memory");
+ c1 = *(((const unsigned char *)s1) - 1);
+ c2 = *(((const unsigned char *)s2) - 1);
+ return (int)c1 - (int)c2;
+}
+#endif /* ARCH_STRING_MEMCMP */
+
+#ifdef ARCH_STRING_STRLEN
+size_t
+strlen(const char *s)
+{
+ size_t n;
+
+ n = (size_t)-1;
+ asm volatile("repne scasb"
+ : "+D" (s), "+c" (n)
+ : "a" (0)
+ : "memory");
+ return ~n - 1;
+}
+#endif /* ARCH_STRING_STRLEN */
+
+#ifdef ARCH_STRING_STRCPY
+char *
+strcpy(char *dest, const char *src)
+{
+ char *orig_dest;
+
+ orig_dest = dest;
+ asm volatile("1:\n"
+ "lodsb\n"
+ "stosb\n"
+ "testb %%al, %%al\n"
+ "jnz 1b\n"
+ : "+D" (dest), "+S" (src)
+ : : "al", "memory");
+ return orig_dest;
+}
+#endif /* ARCH_STRING_STRCPY */
+
+#ifdef ARCH_STRING_STRCMP
+int
+strcmp(const char *s1, const char *s2)
+{
+ unsigned char c1, c2;
+
+ asm volatile("1:\n"
+ "lodsb\n"
+ "scasb\n"
+ "jne 1f\n"
+ "testb %%al, %%al\n"
+ "jnz 1b\n"
+ "1:\n"
+ : "+D" (s1), "+S" (s2)
+ : : "al", "memory");
+ c1 = *(((const unsigned char *)s1) - 1);
+ c2 = *(((const unsigned char *)s2) - 1);
+ return (int)c1 - (int)c2;
+}
+#endif /* ARCH_STRING_STRCMP */