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