ARM: zImage: gather some string functions into string.c
authorNicolas Pitre <nicolas.pitre@linaro.org>
Wed, 14 Sep 2011 01:42:55 +0000 (21:42 -0400)
committerNicolas Pitre <nico@fluxnic.net>
Wed, 14 Sep 2011 17:51:58 +0000 (13:51 -0400)
This is a small subset of string functions needed by commits to come.
Except for memcpy() which is unchanged from its original location, their
implementation is meant to be small, and -Os is enforced to prevent gcc
from doing pointless loop unrolling.

Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
Tested-by: Dave Martin <dave.martin@linaro.org>
Tested-by: Thomas Abraham <thomas.abraham@linaro.org>
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/misc.c
arch/arm/boot/compressed/string.c [new file with mode: 0644]

index 4867647b97965df0a1817fadb7b0351cdcd45e4e..c20ddc69d95014caff6f441f9712080813791340 100644 (file)
@@ -26,6 +26,10 @@ HEAD = head.o
 OBJS   += misc.o decompress.o
 FONTC  = $(srctree)/drivers/video/console/font_acorn_8x8.c
 
+# string library code (-Os is enforced to keep it much smaller)
+OBJS           += string.o
+CFLAGS_string.o        := -Os
+
 #
 # Architecture dependencies
 #
index 832d37236c59fdc92c852166d64a6b0c6efc71d5..8e2a8fca5ed205bcbfda7faafa1eb0d7628a863b 100644 (file)
 
 unsigned int __machine_arch_type;
 
-#define _LINUX_STRING_H_
-
 #include <linux/compiler.h>    /* for inline */
-#include <linux/types.h>       /* for size_t */
-#include <linux/stddef.h>      /* for NULL */
+#include <linux/types.h>
 #include <linux/linkage.h>
-#include <asm/string.h>
-
 
 static void putstr(const char *ptr);
 extern void error(char *x);
@@ -101,41 +96,6 @@ static void putstr(const char *ptr)
        flush();
 }
 
-
-void *memcpy(void *__dest, __const void *__src, size_t __n)
-{
-       int i = 0;
-       unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
-
-       for (i = __n >> 3; i > 0; i--) {
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-       }
-
-       if (__n & 1 << 2) {
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-               *d++ = *s++;
-       }
-
-       if (__n & 1 << 1) {
-               *d++ = *s++;
-               *d++ = *s++;
-       }
-
-       if (__n & 1)
-               *d++ = *s++;
-
-       return __dest;
-}
-
 /*
  * gzip declarations
  */
diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c
new file mode 100644 (file)
index 0000000..36e53ef
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/boot/compressed/string.c
+ *
+ * Small subset of simple string routines
+ */
+
+#include <linux/string.h>
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+       int i = 0;
+       unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
+
+       for (i = __n >> 3; i > 0; i--) {
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+       }
+
+       if (__n & 1 << 2) {
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+               *d++ = *s++;
+       }
+
+       if (__n & 1 << 1) {
+               *d++ = *s++;
+               *d++ = *s++;
+       }
+
+       if (__n & 1)
+               *d++ = *s++;
+
+       return __dest;
+}
+
+void *memmove(void *__dest, __const void *__src, size_t count)
+{
+       unsigned char *d = __dest;
+       const unsigned char *s = __src;
+
+       if (__dest == __src)
+               return __dest;
+
+       if (__dest < __src)
+               return memcpy(__dest, __src, count);
+
+       while (count--)
+               d[count] = s[count];
+       return __dest;
+}
+
+size_t strlen(const char *s)
+{
+       const char *sc = s;
+
+       while (*sc != '\0')
+               sc++;
+       return sc - s;
+}
+
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+       const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
+       int res = 0;
+
+       while (su1 < end) {
+               res = *su1++ - *su2++;
+               if (res)
+                       break;
+       }
+       return res;
+}
+
+int strcmp(const char *cs, const char *ct)
+{
+       unsigned char c1, c2;
+       int res = 0;
+
+       do {
+               c1 = *cs++;
+               c2 = *ct++;
+               res = c1 - c2;
+               if (res)
+                       break;
+       } while (c1);
+       return res;
+}
+
+void *memchr(const void *s, int c, size_t count)
+{
+       const unsigned char *p = s;
+
+       while (count--)
+               if ((unsigned char)c == *p++)
+                       return (void *)(p - 1);
+       return NULL;
+}
+
+char *strchr(const char *s, int c)
+{
+       while (*s != (char)c)
+               if (*s++ == '\0')
+                       return NULL;
+       return (char *)s;
+}
+
+#undef memset
+
+void *memset(void *s, int c, size_t count)
+{
+       char *xs = s;
+       while (count--)
+               *xs++ = c;
+       return s;
+}
+
+void __memzero(void *s, size_t count)
+{
+       memset(s, 0, count);
+}