string.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:12k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef _M68K_STRING_H_
  2. #define _M68K_STRING_H_
  3. #include <asm/setup.h>
  4. #include <asm/page.h>
  5. #define __HAVE_ARCH_STRCPY
  6. static inline char * strcpy(char * dest,const char *src)
  7. {
  8.   char *xdest = dest;
  9.   __asm__ __volatile__
  10.        ("1:tmoveb %1@+,%0@+nt"
  11.         "jne 1b"
  12. : "=a" (dest), "=a" (src)
  13.         : "0" (dest), "1" (src) : "memory");
  14.   return xdest;
  15. }
  16. #define __HAVE_ARCH_STRNCPY
  17. static inline char * strncpy(char *dest, const char *src, size_t n)
  18. {
  19.   char *xdest = dest;
  20.   if (n == 0)
  21.     return xdest;
  22.   __asm__ __volatile__
  23.        ("1:tmoveb %1@+,%0@+nt"
  24. "jeq 2fnt"
  25.         "subql #1,%2nt"
  26.         "jne 1bnt"
  27.         "2:"
  28.         : "=a" (dest), "=a" (src), "=d" (n)
  29.         : "0" (dest), "1" (src), "2" (n)
  30.         : "memory");
  31.   return xdest;
  32. }
  33. #define __HAVE_ARCH_STRCAT
  34. static inline char * strcat(char * dest, const char * src)
  35. {
  36. char *tmp = dest;
  37. while (*dest)
  38. dest++;
  39. while ((*dest++ = *src++))
  40. ;
  41. return tmp;
  42. }
  43. #define __HAVE_ARCH_STRNCAT
  44. static inline char * strncat(char *dest, const char *src, size_t count)
  45. {
  46. char *tmp = dest;
  47. if (count) {
  48. while (*dest)
  49. dest++;
  50. while ((*dest++ = *src++)) {
  51. if (--count == 0) {
  52. *dest++='';
  53. break;
  54. }
  55. }
  56. }
  57. return tmp;
  58. }
  59. #define __HAVE_ARCH_STRCHR
  60. static inline char * strchr(const char * s, int c)
  61. {
  62.   const char ch = c;
  63.   
  64.   for(; *s != ch; ++s)
  65.     if (*s == '')
  66.       return( NULL );
  67.   return( (char *) s);
  68. }
  69. #if 0
  70. #define __HAVE_ARCH_STRPBRK
  71. extern inline char * strpbrk(const char * cs,const char * ct)
  72. {
  73.   const char *sc1,*sc2;
  74.   
  75.   for( sc1 = cs; *sc1 != ''; ++sc1)
  76.     for( sc2 = ct; *sc2 != ''; ++sc2)
  77.       if (*sc1 == *sc2)
  78. return((char *) sc1);
  79.   return( NULL );
  80. }
  81. #endif
  82. #if 0
  83. #define __HAVE_ARCH_STRSPN
  84. static inline size_t strspn(const char *s, const char *accept)
  85. {
  86.   const char *p;
  87.   const char *a;
  88.   size_t count = 0;
  89.   for (p = s; *p != ''; ++p)
  90.     {
  91.       for (a = accept; *a != ''; ++a)
  92.         if (*p == *a)
  93.           break;
  94.       if (*a == '')
  95.         return count;
  96.       else
  97.         ++count;
  98.     }
  99.   return count;
  100. }
  101. #endif
  102. #if 0
  103. #define __HAVE_ARCH_STRTOK
  104. extern inline char * strtok(char * s,const char * ct)
  105. {
  106.   char *sbegin, *send;
  107.   
  108.   sbegin  = s ? s : ___strtok;
  109.   if (!sbegin) {
  110.   return NULL;
  111.   }
  112.   sbegin += strspn(sbegin,ct);
  113.   if (*sbegin == '') {
  114.     ___strtok = NULL;
  115.     return( NULL );
  116.   }
  117.   send = strpbrk( sbegin, ct);
  118.   if (send && *send != '')
  119.     *send++ = '';
  120.   ___strtok = send;
  121.   return (sbegin);
  122. }
  123. #endif
  124. /* strstr !! */
  125. #define __HAVE_ARCH_STRLEN
  126. static inline size_t strlen(const char * s)
  127. {
  128.   const char *sc;
  129.   for (sc = s; *sc != ''; ++sc) ;
  130.   return(sc - s);
  131. }
  132. /* strnlen !! */
  133. #define __HAVE_ARCH_STRCMP
  134. static inline int strcmp(const char * cs,const char * ct)
  135. {
  136.   char __res;
  137.   __asm__
  138.        ("1:tmoveb %0@+,%2nt" /* get *cs */
  139.         "cmpb %1@+,%2nt"      /* compare a byte */
  140.         "jne  2fnt"           /* not equal, break out */
  141.         "tstb %2nt"           /* at end of cs? */
  142.         "jne  1bnt"           /* no, keep going */
  143.         "jra  3fnt" /* strings are equal */
  144.         "2:tsubb %1@-,%2nt"  /* *cs - *ct */
  145.         "3:"
  146.         : "=a" (cs), "=a" (ct), "=d" (__res)
  147.         : "0" (cs), "1" (ct));
  148.   return __res;
  149. }
  150. #define __HAVE_ARCH_STRNCMP
  151. static inline int strncmp(const char * cs,const char * ct,size_t count)
  152. {
  153.   char __res;
  154.   if (!count)
  155.     return 0;
  156.   __asm__
  157.        ("1:tmovb %0@+,%3nt"          /* get *cs */
  158.         "cmpb   %1@+,%3nt"            /* compare a byte */
  159.         "jne    3fnt"                 /* not equal, break out */
  160.         "tstb   %3nt"                 /* at end of cs? */
  161.         "jeq    4fnt"                 /* yes, all done */
  162.         "subql  #1,%2nt"              /* no, adjust count */
  163.         "jne    1bnt"                 /* more to do, keep going */
  164.         "2:tmoveq #0,%3nt"           /* strings are equal */
  165.         "jra    4fnt"
  166.         "3:tsubb %1@-,%3nt"          /* *cs - *ct */
  167.         "4:"
  168.         : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res)
  169.         : "0" (cs), "1" (ct), "2" (count));
  170.   return __res;
  171. }
  172. #define __HAVE_ARCH_MEMSET
  173. /*
  174.  * This is really ugly, but its highly optimizatiable by the
  175.  * compiler and is meant as compensation for gcc's missing
  176.  * __builtin_memset(). For the 680[23]0 it might be worth considering
  177.  * the optimal number of misaligned writes compared to the number of
  178.  * tests'n'branches needed to align the destination address. The
  179.  * 680[46]0 doesn't really care due to their copy-back caches.
  180.  * 10/09/96 - Jes Sorensen
  181.  */
  182. static inline void * __memset_g(void * s, int c, size_t count)
  183. {
  184.   void *xs = s;
  185.   size_t temp;
  186.   if (!count)
  187.     return xs;
  188.   c &= 0xff;
  189.   c |= c << 8;
  190.   c |= c << 16;
  191.   if (count < 36){
  192.   long *ls = s;
  193.   switch(count){
  194.   case 32: case 33: case 34: case 35:
  195.   *ls++ = c;
  196.   case 28: case 29: case 30: case 31:
  197.   *ls++ = c;
  198.   case 24: case 25: case 26: case 27:
  199.   *ls++ = c;
  200.   case 20: case 21: case 22: case 23:
  201.   *ls++ = c;
  202.   case 16: case 17: case 18: case 19:
  203.   *ls++ = c;
  204.   case 12: case 13: case 14: case 15:
  205.   *ls++ = c;
  206.   case 8: case 9: case 10: case 11:
  207.   *ls++ = c;
  208.   case 4: case 5: case 6: case 7:
  209.   *ls++ = c;
  210.   break;
  211.   default:
  212.   break;
  213.   }
  214.   s = ls;
  215.   if (count & 0x02){
  216.   short *ss = s;
  217.   *ss++ = c;
  218.   s = ss;
  219.   }
  220.   if (count & 0x01){
  221.   char *cs = s;
  222.   *cs++ = c;
  223.   s = cs;
  224.   }
  225.   return xs;
  226.   }
  227.   if ((long) s & 1)
  228.     {
  229.       char *cs = s;
  230.       *cs++ = c;
  231.       s = cs;
  232.       count--;
  233.     }
  234.   if (count > 2 && (long) s & 2)
  235.     {
  236.       short *ss = s;
  237.       *ss++ = c;
  238.       s = ss;
  239.       count -= 2;
  240.     }
  241.   temp = count >> 2;
  242.   if (temp)
  243.     {
  244.       long *ls = s;
  245.       temp--;
  246.       do
  247. *ls++ = c;
  248.       while (temp--);
  249.       s = ls;
  250.     }
  251.   if (count & 2)
  252.     {
  253.       short *ss = s;
  254.       *ss++ = c;
  255.       s = ss;
  256.     }
  257.   if (count & 1)
  258.     {
  259.       char *cs = s;
  260.       *cs = c;
  261.     }
  262.   return xs;
  263. }
  264. /*
  265.  * __memset_page assumes that data is longword aligned. Most, if not
  266.  * all, of these page sized memsets are performed on page aligned
  267.  * areas, thus we do not need to check if the destination is longword
  268.  * aligned. Of course we suffer a serious performance loss if this is
  269.  * not the case but I think the risk of this ever happening is
  270.  * extremely small. We spend a lot of time clearing pages in
  271.  * get_empty_page() so I think it is worth it anyway. Besides, the
  272.  * 680[46]0 do not really care about misaligned writes due to their
  273.  * copy-back cache.
  274.  *
  275.  * The optimized case for the 680[46]0 is implemented using the move16
  276.  * instruction. My tests showed that this implementation is 35-45%
  277.  * faster than the original implementation using movel, the only
  278.  * caveat is that the destination address must be 16-byte aligned.
  279.  *                                            01/09/96 - Jes Sorensen
  280.  */
  281. static inline void * __memset_page(void * s,int c,size_t count)
  282. {
  283.   unsigned long data, tmp;
  284.   void *xs, *sp;
  285.   xs = sp = s;
  286.   c = c & 255;
  287.   data = c | (c << 8);
  288.   data |= data << 16;
  289. #ifdef CPU_M68040_OR_M68060_ONLY
  290.   if (((unsigned long) s) & 0x0f)
  291.   __memset_g(s, c, count);
  292.   else{
  293.   *((unsigned long *)(s))++ = data;
  294.   *((unsigned long *)(s))++ = data;
  295.   *((unsigned long *)(s))++ = data;
  296.   *((unsigned long *)(s))++ = data;
  297.   __asm__ __volatile__("1:t"
  298.        ".chip 68040nt"
  299.        "move16 %2@+,%0@+nt"
  300.        ".chip 68knt"
  301.        "subqw  #8,%2nt"
  302.        "subqw  #8,%2nt"
  303.        "dbra   %1,1bnt"
  304.        : "=a" (s), "=d" (tmp)
  305.        : "a" (sp), "0" (s), "1" ((count - 16) / 16 - 1)
  306.        );
  307.   }
  308. #else
  309.   __asm__ __volatile__("1:t"
  310.        "movel %2,%0@+nt"
  311.        "movel %2,%0@+nt"
  312.        "movel %2,%0@+nt"
  313.        "movel %2,%0@+nt"
  314.        "movel %2,%0@+nt"
  315.        "movel %2,%0@+nt"
  316.        "movel %2,%0@+nt"
  317.        "movel %2,%0@+nt"
  318.        "dbra  %1,1bnt"
  319.        : "=a" (s), "=d" (tmp)
  320.        : "d" (data), "0" (s), "1" (count / 32 - 1)
  321.        );
  322. #endif
  323.   return xs;
  324. }
  325. extern void *memset(void *,int,__kernel_size_t);
  326. #define __memset_const(s,c,count) 
  327. ((count==PAGE_SIZE) ? 
  328.   __memset_page((s),(c),(count)) : 
  329.   __memset_g((s),(c),(count)))
  330. #define memset(s, c, count) 
  331. (__builtin_constant_p(count) ? 
  332.  __memset_const((s),(c),(count)) : 
  333.  __memset_g((s),(c),(count)))
  334. #define __HAVE_ARCH_MEMCPY
  335. extern void * memcpy(void *, const void *, size_t );
  336. /*
  337.  * __builtin_memcpy() does not handle page-sized memcpys very well,
  338.  * thus following the same assumptions as for page-sized memsets, this
  339.  * function copies page-sized areas using an unrolled loop, without
  340.  * considering alignment.
  341.  *
  342.  * For the 680[46]0 only kernels we use the move16 instruction instead
  343.  * as it writes through the data-cache, invalidating the cache-lines
  344.  * touched. In this way we do not use up the entire data-cache (well,
  345.  * half of it on the 68060) by copying a page. An unrolled loop of two
  346.  * move16 instructions seem to the fastest. The only caveat is that
  347.  * both source and destination must be 16-byte aligned, if not we fall
  348.  * back to the generic memcpy function.  - Jes
  349.  */
  350. static inline void * __memcpy_page(void * to, const void * from, size_t count)
  351. {
  352.   unsigned long tmp;
  353.   void *xto = to;
  354. #ifdef CPU_M68040_OR_M68060_ONLY
  355.   if (((unsigned long) to | (unsigned long) from) & 0x0f)
  356.   return memcpy(to, from, count);
  357.   __asm__ __volatile__("1:t"
  358.        ".chip 68040nt"
  359.        "move16 %1@+,%0@+nt"
  360.        "move16 %1@+,%0@+nt"
  361.        ".chip 68knt"
  362.        "dbra  %2,1bnt"
  363.        : "=a" (to), "=a" (from), "=d" (tmp)
  364.        : "0" (to), "1" (from) , "2" (count / 32 - 1)
  365.        );
  366. #else
  367.   __asm__ __volatile__("1:t"
  368.        "movel %1@+,%0@+nt"
  369.        "movel %1@+,%0@+nt"
  370.        "movel %1@+,%0@+nt"
  371.        "movel %1@+,%0@+nt"
  372.        "movel %1@+,%0@+nt"
  373.        "movel %1@+,%0@+nt"
  374.        "movel %1@+,%0@+nt"
  375.        "movel %1@+,%0@+nt"
  376.        "dbra  %2,1bnt"
  377.        : "=a" (to), "=a" (from), "=d" (tmp)
  378.        : "0" (to), "1" (from) , "2" (count / 32 - 1)
  379.        );
  380. #endif
  381.   return xto;
  382. }
  383. #define __memcpy_const(to, from, n) 
  384. ((n==PAGE_SIZE) ? 
  385.   __memcpy_page((to),(from),(n)) : 
  386.   __builtin_memcpy((to),(from),(n)))
  387. #define memcpy(to, from, n) 
  388. (__builtin_constant_p(n) ? 
  389.  __memcpy_const((to),(from),(n)) : 
  390.  memcpy((to),(from),(n)))
  391. #define __HAVE_ARCH_MEMMOVE
  392. static inline void * memmove(void * dest,const void * src, size_t n)
  393. {
  394.   void *xdest = dest;
  395.   size_t temp;
  396.   if (!n)
  397.     return xdest;
  398.   if (dest < src)
  399.     {
  400.       if ((long) dest & 1)
  401. {
  402.   char *cdest = dest;
  403.   const char *csrc = src;
  404.   *cdest++ = *csrc++;
  405.   dest = cdest;
  406.   src = csrc;
  407.   n--;
  408. }
  409.       if (n > 2 && (long) dest & 2)
  410. {
  411.   short *sdest = dest;
  412.   const short *ssrc = src;
  413.   *sdest++ = *ssrc++;
  414.   dest = sdest;
  415.   src = ssrc;
  416.   n -= 2;
  417. }
  418.       temp = n >> 2;
  419.       if (temp)
  420. {
  421.   long *ldest = dest;
  422.   const long *lsrc = src;
  423.   temp--;
  424.   do
  425.     *ldest++ = *lsrc++;
  426.   while (temp--);
  427.   dest = ldest;
  428.   src = lsrc;
  429. }
  430.       if (n & 2)
  431. {
  432.   short *sdest = dest;
  433.   const short *ssrc = src;
  434.   *sdest++ = *ssrc++;
  435.   dest = sdest;
  436.   src = ssrc;
  437. }
  438.       if (n & 1)
  439. {
  440.   char *cdest = dest;
  441.   const char *csrc = src;
  442.   *cdest = *csrc;
  443. }
  444.     }
  445.   else
  446.     {
  447.       dest = (char *) dest + n;
  448.       src = (const char *) src + n;
  449.       if ((long) dest & 1)
  450. {
  451.   char *cdest = dest;
  452.   const char *csrc = src;
  453.   *--cdest = *--csrc;
  454.   dest = cdest;
  455.   src = csrc;
  456.   n--;
  457. }
  458.       if (n > 2 && (long) dest & 2)
  459. {
  460.   short *sdest = dest;
  461.   const short *ssrc = src;
  462.   *--sdest = *--ssrc;
  463.   dest = sdest;
  464.   src = ssrc;
  465.   n -= 2;
  466. }
  467.       temp = n >> 2;
  468.       if (temp)
  469. {
  470.   long *ldest = dest;
  471.   const long *lsrc = src;
  472.   temp--;
  473.   do
  474.     *--ldest = *--lsrc;
  475.   while (temp--);
  476.   dest = ldest;
  477.   src = lsrc;
  478. }
  479.       if (n & 2)
  480. {
  481.   short *sdest = dest;
  482.   const short *ssrc = src;
  483.   *--sdest = *--ssrc;
  484.   dest = sdest;
  485.   src = ssrc;
  486. }
  487.       if (n & 1)
  488. {
  489.   char *cdest = dest;
  490.   const char *csrc = src;
  491.   *--cdest = *--csrc;
  492. }
  493.     }
  494.   return xdest;
  495. }
  496. #define __HAVE_ARCH_MEMCMP
  497. extern int memcmp(const void * ,const void * ,size_t );
  498. #define memcmp(cs, ct, n) 
  499. (__builtin_constant_p(n) ? 
  500.  __builtin_memcmp((cs),(ct),(n)) : 
  501.  memcmp((cs),(ct),(n)))
  502. #define __HAVE_ARCH_MEMCHR
  503. extern inline void * memchr(const void * cs, int c, size_t count) {
  504. /* Someone else can optimize this, I don't care - tonym@mac.linux-m68k.org */
  505. unsigned char *ret = (unsigned char *)cs;
  506. for(;count>0;count--,ret++)
  507. if(*ret == c) return ret;
  508. return NULL;
  509. }
  510. #endif /* _M68K_STRING_H_ */