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