1/* $Id: string.h,v 1.1.1.1 2008/10/15 03:29:18 james26_jang Exp $
2 * string.h: External definitions for optimized assembly string
3 *           routines for the Linux Kernel.
4 *
5 * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
6 * Copyright (C) 1996,1997,1999 Jakub Jelinek (jakub@redhat.com)
7 */
8
9#ifndef __SPARC64_STRING_H__
10#define __SPARC64_STRING_H__
11
12/* Really, userland/ksyms should not see any of this stuff. */
13
14#ifdef __KERNEL__
15
16#include <asm/asi.h>
17
18extern void __memmove(void *,const void *,__kernel_size_t);
19extern __kernel_size_t __memcpy(void *,const void *,__kernel_size_t);
20extern void *__memset(void *,int,__kernel_size_t);
21extern void *__builtin_memcpy(void *,const void *,__kernel_size_t);
22extern void *__builtin_memset(void *,int,__kernel_size_t);
23
24#ifndef EXPORT_SYMTAB_STROPS
25
26/* First the mem*() things. */
27#define __HAVE_ARCH_BCOPY
28#define __HAVE_ARCH_MEMMOVE
29
30#undef memmove
31#define memmove(_to, _from, _n) \
32({ \
33	void *_t = (_to); \
34	__memmove(_t, (_from), (_n)); \
35	_t; \
36})
37
38#define __HAVE_ARCH_MEMCPY
39
40static inline void *__constant_memcpy(void *to, const void *from, __kernel_size_t n)
41{
42	if(n) {
43		if(n <= 32) {
44			__builtin_memcpy(to, from, n);
45		} else {
46			__memcpy(to, from, n);
47		}
48	}
49	return to;
50}
51
52static inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_size_t n)
53{
54	__memcpy(to, from, n);
55	return to;
56}
57
58#undef memcpy
59#define memcpy(t, f, n) \
60(__builtin_constant_p(n) ? \
61 __constant_memcpy((t),(f),(n)) : \
62 __nonconstant_memcpy((t),(f),(n)))
63
64#define __HAVE_ARCH_MEMSET
65
66static inline void *__constant_memset(void *s, int c, __kernel_size_t count)
67{
68	extern __kernel_size_t __bzero(void *, __kernel_size_t);
69
70	if(!c) {
71		__bzero(s, count);
72		return s;
73	} else
74		return __memset(s, c, count);
75}
76
77#undef memset
78#define memset(s, c, count) \
79((__builtin_constant_p(count) && (count) <= 32) ? \
80 __builtin_memset((s), (c), (count)) : \
81 (__builtin_constant_p(c) ? \
82  __constant_memset((s), (c), (count)) : \
83  __memset((s), (c), (count))))
84
85#define __HAVE_ARCH_MEMSCAN
86
87#undef memscan
88#define memscan(__arg0, __char, __arg2)						\
89({										\
90	extern void *__memscan_zero(void *, size_t);				\
91	extern void *__memscan_generic(void *, int, size_t);			\
92	void *__retval, *__addr = (__arg0);					\
93	size_t __size = (__arg2);						\
94										\
95	if(__builtin_constant_p(__char) && !(__char))				\
96		__retval = __memscan_zero(__addr, __size);			\
97	else									\
98		__retval = __memscan_generic(__addr, (__char), __size);		\
99										\
100	__retval;								\
101})
102
103#define __HAVE_ARCH_MEMCMP
104extern int memcmp(const void *,const void *,__kernel_size_t);
105
106/* Now the str*() stuff... */
107#define __HAVE_ARCH_STRLEN
108
109extern __kernel_size_t __strlen(const char *);
110extern __kernel_size_t strlen(const char *);
111
112#define __HAVE_ARCH_STRNCMP
113
114extern int __strncmp(const char *, const char *, __kernel_size_t);
115
116static inline int __constant_strncmp(const char *src, const char *dest, __kernel_size_t count)
117{
118	register int retval;
119	switch(count) {
120	case 0: return 0;
121	case 1: return (src[0] - dest[0]);
122	case 2: retval = (src[0] - dest[0]);
123		if(!retval && src[0])
124		  retval = (src[1] - dest[1]);
125		return retval;
126	case 3: retval = (src[0] - dest[0]);
127		if(!retval && src[0]) {
128		  retval = (src[1] - dest[1]);
129		  if(!retval && src[1])
130		    retval = (src[2] - dest[2]);
131		}
132		return retval;
133	case 4: retval = (src[0] - dest[0]);
134		if(!retval && src[0]) {
135		  retval = (src[1] - dest[1]);
136		  if(!retval && src[1]) {
137		    retval = (src[2] - dest[2]);
138		    if (!retval && src[2])
139		      retval = (src[3] - dest[3]);
140		  }
141		}
142		return retval;
143	case 5: retval = (src[0] - dest[0]);
144		if(!retval && src[0]) {
145		  retval = (src[1] - dest[1]);
146		  if(!retval && src[1]) {
147		    retval = (src[2] - dest[2]);
148		    if (!retval && src[2]) {
149		      retval = (src[3] - dest[3]);
150		      if (!retval && src[3])
151		        retval = (src[4] - dest[4]);
152		    }
153		  }
154		}
155		return retval;
156	default:
157		retval = (src[0] - dest[0]);
158		if(!retval && src[0]) {
159		  retval = (src[1] - dest[1]);
160		  if(!retval && src[1]) {
161		    retval = (src[2] - dest[2]);
162		    if(!retval && src[2])
163		      retval = __strncmp(src+3,dest+3,count-3);
164		  }
165		}
166		return retval;
167	}
168}
169
170#undef strncmp
171#define strncmp(__arg0, __arg1, __arg2)	\
172(__builtin_constant_p(__arg2) ?	\
173 __constant_strncmp(__arg0, __arg1, __arg2) : \
174 __strncmp(__arg0, __arg1, __arg2))
175
176#endif /* !EXPORT_SYMTAB_STROPS */
177
178#endif /* __KERNEL__ */
179
180#endif /* !(__SPARC64_STRING_H__) */
181