aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
authorRobin Getz <robin.getz@analog.com>2010-05-03 13:23:20 -0400
committerMike Frysinger <vapier@gentoo.org>2010-05-22 14:19:09 -0400
commit479ba6035862a9c08ce4351c7fff8926fde4ede5 (patch)
tree93a6419ffdfd38056f26d4362de450f79af044b3 /arch/blackfin
parent80fcdb959343ab9e0ee95c11b5ea47c44a2c3004 (diff)
Blackfin: move string functions to normal lib/ assembly
Since 'extern inline' doesn't work correctly in the context of the Linux kernel (too many overriding defines), move the string functions to normal lib/ assembly files (like the existing mem funcs). This avoids the forced inline all over the kernel and allows us to place them constantly in L1. This also avoids some module failures when gcc inserts calls to string functions but the kernel build system doesn't fully consult the library archives. Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/Kconfig28
-rw-r--r--arch/blackfin/include/asm/string.h113
-rw-r--r--arch/blackfin/kernel/bfin_ksyms.c12
-rw-r--r--arch/blackfin/lib/strcmp.S43
-rw-r--r--arch/blackfin/lib/strcmp.c19
-rw-r--r--arch/blackfin/lib/strcpy.S35
-rw-r--r--arch/blackfin/lib/strcpy.c19
-rw-r--r--arch/blackfin/lib/strncmp.S52
-rw-r--r--arch/blackfin/lib/strncmp.c18
-rw-r--r--arch/blackfin/lib/strncpy.S52
-rw-r--r--arch/blackfin/lib/strncpy.c19
11 files changed, 226 insertions, 184 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 405bdaa17333..7b9fc9c9c0c2 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -791,6 +791,34 @@ config MEMCPY_L1
791 If enabled, the memcpy function is linked 791 If enabled, the memcpy function is linked
792 into L1 instruction memory. (less latency) 792 into L1 instruction memory. (less latency)
793 793
794config STRCMP_L1
795 bool "locate strcmp function in L1 Memory"
796 default y
797 help
798 If enabled, the strcmp function is linked
799 into L1 instruction memory (less latency).
800
801config STRNCMP_L1
802 bool "locate strncmp function in L1 Memory"
803 default y
804 help
805 If enabled, the strncmp function is linked
806 into L1 instruction memory (less latency).
807
808config STRCPY_L1
809 bool "locate strcpy function in L1 Memory"
810 default y
811 help
812 If enabled, the strcpy function is linked
813 into L1 instruction memory (less latency).
814
815config STRNCPY_L1
816 bool "locate strncpy function in L1 Memory"
817 default y
818 help
819 If enabled, the strncpy function is linked
820 into L1 instruction memory (less latency).
821
794config SYS_BFIN_SPINLOCK_L1 822config SYS_BFIN_SPINLOCK_L1
795 bool "Locate sys_bfin_spinlock function in L1 Memory" 823 bool "Locate sys_bfin_spinlock function in L1 Memory"
796 default y 824 default y
diff --git a/arch/blackfin/include/asm/string.h b/arch/blackfin/include/asm/string.h
index d7f0ccb418c3..423c099aa988 100644
--- a/arch/blackfin/include/asm/string.h
+++ b/arch/blackfin/include/asm/string.h
@@ -12,121 +12,16 @@
12#ifdef __KERNEL__ /* only set these up for kernel code */ 12#ifdef __KERNEL__ /* only set these up for kernel code */
13 13
14#define __HAVE_ARCH_STRCPY 14#define __HAVE_ARCH_STRCPY
15extern inline char *strcpy(char *dest, const char *src) 15extern char *strcpy(char *dest, const char *src);
16{
17 char *xdest = dest;
18 char temp = 0;
19
20 __asm__ __volatile__ (
21 "1:"
22 "%2 = B [%1++] (Z);"
23 "B [%0++] = %2;"
24 "CC = %2;"
25 "if cc jump 1b (bp);"
26 : "+&a" (dest), "+&a" (src), "=&d" (temp)
27 :
28 : "memory", "CC");
29
30 return xdest;
31}
32 16
33#define __HAVE_ARCH_STRNCPY 17#define __HAVE_ARCH_STRNCPY
34extern inline char *strncpy(char *dest, const char *src, size_t n) 18extern char *strncpy(char *dest, const char *src, size_t n);
35{
36 char *xdest = dest;
37 char temp = 0;
38
39 if (n == 0)
40 return xdest;
41
42 __asm__ __volatile__ (
43 "1:"
44 "%3 = B [%1++] (Z);"
45 "B [%0++] = %3;"
46 "CC = %3;"
47 "if ! cc jump 2f;"
48 "%2 += -1;"
49 "CC = %2 == 0;"
50 "if ! cc jump 1b (bp);"
51 "jump 4f;"
52 "2:"
53 /* if src is shorter than n, we need to null pad bytes now */
54 "%3 = 0;"
55 "3:"
56 "%2 += -1;"
57 "CC = %2 == 0;"
58 "if cc jump 4f;"
59 "B [%0++] = %3;"
60 "jump 3b;"
61 "4:"
62 : "+&a" (dest), "+&a" (src), "+&da" (n), "=&d" (temp)
63 :
64 : "memory", "CC");
65
66 return xdest;
67}
68 19
69#define __HAVE_ARCH_STRCMP 20#define __HAVE_ARCH_STRCMP
70extern inline int strcmp(const char *cs, const char *ct) 21extern int strcmp(const char *cs, const char *ct);
71{
72 /* need to use int's here so the char's in the assembly don't get
73 * sign extended incorrectly when we don't want them to be
74 */
75 int __res1, __res2;
76
77 __asm__ __volatile__ (
78 "1:"
79 "%2 = B[%0++] (Z);" /* get *cs */
80 "%3 = B[%1++] (Z);" /* get *ct */
81 "CC = %2 == %3;" /* compare a byte */
82 "if ! cc jump 2f;" /* not equal, break out */
83 "CC = %2;" /* at end of cs? */
84 "if cc jump 1b (bp);" /* no, keep going */
85 "jump.s 3f;" /* strings are equal */
86 "2:"
87 "%2 = %2 - %3;" /* *cs - *ct */
88 "3:"
89 : "+&a" (cs), "+&a" (ct), "=&d" (__res1), "=&d" (__res2)
90 :
91 : "memory", "CC");
92
93 return __res1;
94}
95 22
96#define __HAVE_ARCH_STRNCMP 23#define __HAVE_ARCH_STRNCMP
97extern inline int strncmp(const char *cs, const char *ct, size_t count) 24extern int strncmp(const char *cs, const char *ct, size_t count);
98{
99 /* need to use int's here so the char's in the assembly don't get
100 * sign extended incorrectly when we don't want them to be
101 */
102 int __res1, __res2;
103
104 if (!count)
105 return 0;
106
107 __asm__ __volatile__ (
108 "1:"
109 "%3 = B[%0++] (Z);" /* get *cs */
110 "%4 = B[%1++] (Z);" /* get *ct */
111 "CC = %3 == %4;" /* compare a byte */
112 "if ! cc jump 3f;" /* not equal, break out */
113 "CC = %3;" /* at end of cs? */
114 "if ! cc jump 4f;" /* yes, all done */
115 "%2 += -1;" /* no, adjust count */
116 "CC = %2 == 0;"
117 "if ! cc jump 1b;" /* more to do, keep going */
118 "2:"
119 "%3 = 0;" /* strings are equal */
120 "jump.s 4f;"
121 "3:"
122 "%3 = %3 - %4;" /* *cs - *ct */
123 "4:"
124 : "+&a" (cs), "+&a" (ct), "+&da" (count), "=&d" (__res1), "=&d" (__res2)
125 :
126 : "memory", "CC");
127
128 return __res1;
129}
130 25
131#define __HAVE_ARCH_MEMSET 26#define __HAVE_ARCH_MEMSET
132extern void *memset(void *s, int c, size_t count); 27extern void *memset(void *s, int c, size_t count);
diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c
index ed8392c117ea..2c264b51566a 100644
--- a/arch/blackfin/kernel/bfin_ksyms.c
+++ b/arch/blackfin/kernel/bfin_ksyms.c
@@ -33,6 +33,18 @@ EXPORT_SYMBOL(memmove);
33EXPORT_SYMBOL(memchr); 33EXPORT_SYMBOL(memchr);
34 34
35/* 35/*
36 * Because string functions are both inline and exported functions and
37 * folder arch/blackfin/lib is configured as a library path in Makefile,
38 * symbols exported in folder lib is not linked into built-in.o but
39 * inlined only. In order to export string symbols to kernel module
40 * properly, they should be exported here.
41 */
42EXPORT_SYMBOL(strcpy);
43EXPORT_SYMBOL(strncpy);
44EXPORT_SYMBOL(strcmp);
45EXPORT_SYMBOL(strncmp);
46
47/*
36 * libgcc functions - functions that are used internally by the 48 * libgcc functions - functions that are used internally by the
37 * compiler... (prototypes are not correct though, but that 49 * compiler... (prototypes are not correct though, but that
38 * doesn't really matter since they're not versioned). 50 * doesn't really matter since they're not versioned).
diff --git a/arch/blackfin/lib/strcmp.S b/arch/blackfin/lib/strcmp.S
new file mode 100644
index 000000000000..d7c1d158973b
--- /dev/null
+++ b/arch/blackfin/lib/strcmp.S
@@ -0,0 +1,43 @@
1/*
2 * Copyright 2005-2010 Analog Devices Inc.
3 *
4 * Licensed under the ADI BSD license or the GPL-2 (or later)
5 */
6
7#include <linux/linkage.h>
8
9/* void *strcmp(char *s1, const char *s2);
10 * R0 = address (s1)
11 * R1 = address (s2)
12 *
13 * Returns an integer less than, equal to, or greater than zero if s1
14 * (or the first n bytes thereof) is found, respectively, to be less
15 * than, to match, or be greater than s2.
16 */
17
18#ifdef CONFIG_STRCMP_L1
19.section .l1.text
20#else
21.text
22#endif
23
24.align 2
25
26ENTRY(_strcmp)
27 P0 = R0 ; /* s1 */
28 P1 = R1 ; /* s2 */
29
301:
31 R0 = B[P0++] (Z); /* get *s1 */
32 R1 = B[P1++] (Z); /* get *s2 */
33 CC = R0 == R1; /* compare a byte */
34 if ! cc jump 2f; /* not equal, break out */
35 CC = R0; /* at end of s1? */
36 if cc jump 1b (bp); /* no, keep going */
37 jump.s 3f; /* strings are equal */
382:
39 R0 = R0 - R1; /* *s1 - *s2 */
403:
41 RTS;
42
43ENDPROC(_strcmp)
diff --git a/arch/blackfin/lib/strcmp.c b/arch/blackfin/lib/strcmp.c
deleted file mode 100644
index fde39a1950ce..000000000000
--- a/arch/blackfin/lib/strcmp.c
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * Provide symbol in case str func is not inlined.
3 *
4 * Copyright (c) 2006-2007 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#define strcmp __inline_strcmp
10#include <asm/string.h>
11#undef strcmp
12
13#include <linux/module.h>
14
15int strcmp(const char *dest, const char *src)
16{
17 return __inline_strcmp(dest, src);
18}
19EXPORT_SYMBOL(strcmp);
diff --git a/arch/blackfin/lib/strcpy.S b/arch/blackfin/lib/strcpy.S
new file mode 100644
index 000000000000..a6a0c6363806
--- /dev/null
+++ b/arch/blackfin/lib/strcpy.S
@@ -0,0 +1,35 @@
1/*
2 * Copyright 2005-2010 Analog Devices Inc.
3 *
4 * Licensed under the ADI BSD license or the GPL-2 (or later)
5 */
6
7#include <linux/linkage.h>
8
9/* void *strcpy(char *dest, const char *src);
10 * R0 = address (dest)
11 * R1 = address (src)
12 *
13 * Returns a pointer to the destination string dest
14 */
15
16#ifdef CONFIG_STRCPY_L1
17.section .l1.text
18#else
19.text
20#endif
21
22.align 2
23
24ENTRY(_strcpy)
25 P0 = R0 ; /* dst*/
26 P1 = R1 ; /* src*/
27
281:
29 R1 = B [P1++] (Z);
30 B [P0++] = R1;
31 CC = R1;
32 if cc jump 1b (bp);
33 RTS;
34
35ENDPROC(_strcpy)
diff --git a/arch/blackfin/lib/strcpy.c b/arch/blackfin/lib/strcpy.c
deleted file mode 100644
index 2a8836b1f4d3..000000000000
--- a/arch/blackfin/lib/strcpy.c
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * Provide symbol in case str func is not inlined.
3 *
4 * Copyright (c) 2006-2007 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#define strcpy __inline_strcpy
10#include <asm/string.h>
11#undef strcpy
12
13#include <linux/module.h>
14
15char *strcpy(char *dest, const char *src)
16{
17 return __inline_strcpy(dest, src);
18}
19EXPORT_SYMBOL(strcpy);
diff --git a/arch/blackfin/lib/strncmp.S b/arch/blackfin/lib/strncmp.S
new file mode 100644
index 000000000000..6da37c34a847
--- /dev/null
+++ b/arch/blackfin/lib/strncmp.S
@@ -0,0 +1,52 @@
1/*
2 * Copyright 2005-2010 Analog Devices Inc.
3 *
4 * Licensed under the ADI BSD license or the GPL-2 (or later)
5 */
6
7#include <linux/linkage.h>
8
9/* void *strncpy(char *s1, const char *s2, size_t n);
10 * R0 = address (dest)
11 * R1 = address (src)
12 * R2 = size (n)
13 * Returns a pointer to the destination string dest
14 */
15
16#ifdef CONFIG_STRNCMP_L1
17.section .l1.text
18#else
19.text
20#endif
21
22.align 2
23
24ENTRY(_strncmp)
25 CC = R2 == 0;
26 if CC JUMP 5f;
27
28 P0 = R0 ; /* s1 */
29 P1 = R1 ; /* s2 */
301:
31 R0 = B[P0++] (Z); /* get *s1 */
32 R1 = B[P1++] (Z); /* get *s2 */
33 CC = R0 == R1; /* compare a byte */
34 if ! cc jump 3f; /* not equal, break out */
35 CC = R0; /* at end of s1? */
36 if ! cc jump 4f; /* yes, all done */
37 R2 += -1; /* no, adjust count */
38 CC = R2 == 0;
39 if ! cc jump 1b (bp); /* more to do, keep going */
402:
41 R0 = 0; /* strings are equal */
42 jump.s 4f;
433:
44 R0 = R0 - R1; /* *s1 - *s2 */
454:
46 RTS;
47
485:
49 R0 = 0;
50 RTS;
51
52ENDPROC(_strncmp)
diff --git a/arch/blackfin/lib/strncmp.c b/arch/blackfin/lib/strncmp.c
deleted file mode 100644
index 46518b1d2983..000000000000
--- a/arch/blackfin/lib/strncmp.c
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * Provide symbol in case str func is not inlined.
3 *
4 * Copyright (c) 2006-2007 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#define strncmp __inline_strncmp
10#include <asm/string.h>
11#include <linux/module.h>
12#undef strncmp
13
14int strncmp(const char *cs, const char *ct, size_t count)
15{
16 return __inline_strncmp(cs, ct, count);
17}
18EXPORT_SYMBOL(strncmp);
diff --git a/arch/blackfin/lib/strncpy.S b/arch/blackfin/lib/strncpy.S
new file mode 100644
index 000000000000..39fbbe6523e5
--- /dev/null
+++ b/arch/blackfin/lib/strncpy.S
@@ -0,0 +1,52 @@
1/*
2 * Copyright 2005-2010 Analog Devices Inc.
3 *
4 * Licensed under the ADI BSD license or the GPL-2 (or later)
5 */
6
7#include <linux/linkage.h>
8
9/* void *strncpy(char *dest, const char *src, size_t n);
10 * R0 = address (dest)
11 * R1 = address (src)
12 * R2 = size
13 * Returns a pointer to the destination string dest
14 */
15
16#ifdef CONFIG_STRNCPY_L1
17.section .l1.text
18#else
19.text
20#endif
21
22.align 2
23
24ENTRY(_strncpy)
25 CC = R2 == 0;
26 if CC JUMP 4f;
27 P0 = R0 ; /* dst*/
28 P1 = R1 ; /* src*/
29
301:
31 R1 = B [P1++] (Z);
32 B [P0++] = R1;
33 CC = R1;
34 if ! cc jump 2f;
35 R2 += -1;
36 CC = R2 == 0;
37 if ! cc jump 1b (bp);
38 jump 4f;
392:
40 /* if src is shorter than n, we need to null pad bytes in dest */
41 R1 = 0;
423:
43 R2 += -1;
44 CC = R2 == 0;
45 if cc jump 4f;
46 B [P0++] = R1;
47 jump 3b;
48
494:
50 RTS;
51
52ENDPROC(_strncpy)
diff --git a/arch/blackfin/lib/strncpy.c b/arch/blackfin/lib/strncpy.c
deleted file mode 100644
index ea1dc6bf2373..000000000000
--- a/arch/blackfin/lib/strncpy.c
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * Provide symbol in case str func is not inlined.
3 *
4 * Copyright (c) 2006-2007 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#define strncpy __inline_strncpy
10#include <asm/string.h>
11#undef strncpy
12
13#include <linux/module.h>
14
15char *strncpy(char *dest, const char *src, size_t n)
16{
17 return __inline_strncpy(dest, src, n);
18}
19EXPORT_SYMBOL(strncpy);