linux/arch/sparc/include/asm/string_32.h
<<
>>
Prefs
   1/*
   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__) */
 206