string.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:12k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef _I386_STRING_H_
  2. #define _I386_STRING_H_
  3. #ifdef __KERNEL__
  4. #include <linux/config.h>
  5. /*
  6.  * On a 486 or Pentium, we are better off not using the
  7.  * byte string operations. But on a 386 or a PPro the
  8.  * byte string ops are faster than doing it by hand
  9.  * (MUCH faster on a Pentium).
  10.  *
  11.  * Also, the byte strings actually work correctly. Forget
  12.  * the i486 routines for now as they may be broken..
  13.  */
  14. #if FIXED_486_STRING && defined(CONFIG_X86_USE_STRING_486)
  15. #include <asm/string-486.h>
  16. #else
  17. /*
  18.  * This string-include defines all string functions as inline
  19.  * functions. Use gcc. It also assumes ds=es=data space, this should be
  20.  * normal. Most of the string-functions are rather heavily hand-optimized,
  21.  * see especially strtok,strstr,str[c]spn. They should work, but are not
  22.  * very easy to understand. Everything is done entirely within the register
  23.  * set, making the functions fast and clean. String instructions have been
  24.  * used through-out, making for "slightly" unclear code :-)
  25.  *
  26.  * NO Copyright (C) 1991, 1992 Linus Torvalds,
  27.  * consider these trivial functions to be PD.
  28.  */
  29. #define __HAVE_ARCH_STRCPY
  30. static inline char * strcpy(char * dest,const char *src)
  31. {
  32. int d0, d1, d2;
  33. __asm__ __volatile__(
  34. "1:tlodsbnt"
  35. "stosbnt"
  36. "testb %%al,%%alnt"
  37. "jne 1b"
  38. : "=&S" (d0), "=&D" (d1), "=&a" (d2)
  39. :"0" (src),"1" (dest) : "memory");
  40. return dest;
  41. }
  42. #define __HAVE_ARCH_STRNCPY
  43. static inline char * strncpy(char * dest,const char *src,size_t count)
  44. {
  45. int d0, d1, d2, d3;
  46. __asm__ __volatile__(
  47. "1:tdecl %2nt"
  48. "js 2fnt"
  49. "lodsbnt"
  50. "stosbnt"
  51. "testb %%al,%%alnt"
  52. "jne 1bnt"
  53. "repnt"
  54. "stosbn"
  55. "2:"
  56. : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
  57. :"0" (src),"1" (dest),"2" (count) : "memory");
  58. return dest;
  59. }
  60. #define __HAVE_ARCH_STRCAT
  61. static inline char * strcat(char * dest,const char * src)
  62. {
  63. int d0, d1, d2, d3;
  64. __asm__ __volatile__(
  65. "repnent"
  66. "scasbnt"
  67. "decl %1n"
  68. "1:tlodsbnt"
  69. "stosbnt"
  70. "testb %%al,%%alnt"
  71. "jne 1b"
  72. : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
  73. : "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
  74. return dest;
  75. }
  76. #define __HAVE_ARCH_STRNCAT
  77. static inline char * strncat(char * dest,const char * src,size_t count)
  78. {
  79. int d0, d1, d2, d3;
  80. __asm__ __volatile__(
  81. "repnent"
  82. "scasbnt"
  83. "decl %1nt"
  84. "movl %8,%3n"
  85. "1:tdecl %3nt"
  86. "js 2fnt"
  87. "lodsbnt"
  88. "stosbnt"
  89. "testb %%al,%%alnt"
  90. "jne 1bn"
  91. "2:txorl %2,%2nt"
  92. "stosb"
  93. : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
  94. : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
  95. : "memory");
  96. return dest;
  97. }
  98. #define __HAVE_ARCH_STRCMP
  99. static inline int strcmp(const char * cs,const char * ct)
  100. {
  101. int d0, d1;
  102. register int __res;
  103. __asm__ __volatile__(
  104. "1:tlodsbnt"
  105. "scasbnt"
  106. "jne 2fnt"
  107. "testb %%al,%%alnt"
  108. "jne 1bnt"
  109. "xorl %%eax,%%eaxnt"
  110. "jmp 3fn"
  111. "2:tsbbl %%eax,%%eaxnt"
  112. "orb $1,%%aln"
  113. "3:"
  114. :"=a" (__res), "=&S" (d0), "=&D" (d1)
  115.      :"1" (cs),"2" (ct));
  116. return __res;
  117. }
  118. #define __HAVE_ARCH_STRNCMP
  119. static inline int strncmp(const char * cs,const char * ct,size_t count)
  120. {
  121. register int __res;
  122. int d0, d1, d2;
  123. __asm__ __volatile__(
  124. "1:tdecl %3nt"
  125. "js 2fnt"
  126. "lodsbnt"
  127. "scasbnt"
  128. "jne 3fnt"
  129. "testb %%al,%%alnt"
  130. "jne 1bn"
  131. "2:txorl %%eax,%%eaxnt"
  132. "jmp 4fn"
  133. "3:tsbbl %%eax,%%eaxnt"
  134. "orb $1,%%aln"
  135. "4:"
  136.      :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
  137.      :"1" (cs),"2" (ct),"3" (count));
  138. return __res;
  139. }
  140. #define __HAVE_ARCH_STRCHR
  141. static inline char * strchr(const char * s, int c)
  142. {
  143. int d0;
  144. register char * __res;
  145. __asm__ __volatile__(
  146. "movb %%al,%%ahn"
  147. "1:tlodsbnt"
  148. "cmpb %%ah,%%alnt"
  149. "je 2fnt"
  150. "testb %%al,%%alnt"
  151. "jne 1bnt"
  152. "movl $1,%1n"
  153. "2:tmovl %1,%0nt"
  154. "decl %0"
  155. :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
  156. return __res;
  157. }
  158. #define __HAVE_ARCH_STRRCHR
  159. static inline char * strrchr(const char * s, int c)
  160. {
  161. int d0, d1;
  162. register char * __res;
  163. __asm__ __volatile__(
  164. "movb %%al,%%ahn"
  165. "1:tlodsbnt"
  166. "cmpb %%ah,%%alnt"
  167. "jne 2fnt"
  168. "leal -1(%%esi),%0n"
  169. "2:ttestb %%al,%%alnt"
  170. "jne 1b"
  171. :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
  172. return __res;
  173. }
  174. #define __HAVE_ARCH_STRLEN
  175. static inline size_t strlen(const char * s)
  176. {
  177. int d0;
  178. register int __res;
  179. __asm__ __volatile__(
  180. "repnent"
  181. "scasbnt"
  182. "notl %0nt"
  183. "decl %0"
  184. :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
  185. return __res;
  186. }
  187. static inline void * __memcpy(void * to, const void * from, size_t n)
  188. {
  189. int d0, d1, d2;
  190. __asm__ __volatile__(
  191. "rep ; movslnt"
  192. "testb $2,%b4nt"
  193. "je 1fnt"
  194. "movswn"
  195. "1:ttestb $1,%b4nt"
  196. "je 2fnt"
  197. "movsbn"
  198. "2:"
  199. : "=&c" (d0), "=&D" (d1), "=&S" (d2)
  200. :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
  201. : "memory");
  202. return (to);
  203. }
  204. /*
  205.  * This looks horribly ugly, but the compiler can optimize it totally,
  206.  * as the count is constant.
  207.  */
  208. static inline void * __constant_memcpy(void * to, const void * from, size_t n)
  209. {
  210. switch (n) {
  211. case 0:
  212. return to;
  213. case 1:
  214. *(unsigned char *)to = *(const unsigned char *)from;
  215. return to;
  216. case 2:
  217. *(unsigned short *)to = *(const unsigned short *)from;
  218. return to;
  219. case 3:
  220. *(unsigned short *)to = *(const unsigned short *)from;
  221. *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
  222. return to;
  223. case 4:
  224. *(unsigned long *)to = *(const unsigned long *)from;
  225. return to;
  226. case 6: /* for Ethernet addresses */
  227. *(unsigned long *)to = *(const unsigned long *)from;
  228. *(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
  229. return to;
  230. case 8:
  231. *(unsigned long *)to = *(const unsigned long *)from;
  232. *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  233. return to;
  234. case 12:
  235. *(unsigned long *)to = *(const unsigned long *)from;
  236. *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  237. *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
  238. return to;
  239. case 16:
  240. *(unsigned long *)to = *(const unsigned long *)from;
  241. *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  242. *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
  243. *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
  244. return to;
  245. case 20:
  246. *(unsigned long *)to = *(const unsigned long *)from;
  247. *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  248. *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
  249. *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
  250. *(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
  251. return to;
  252. }
  253. #define COMMON(x) 
  254. __asm__ __volatile__( 
  255. "rep ; movsl" 
  256. : "=&c" (d0), "=&D" (d1), "=&S" (d2) 
  257. : "0" (n/4),"1" ((long) to),"2" ((long) from) 
  258. : "memory");
  259. {
  260. int d0, d1, d2;
  261. switch (n % 4) {
  262. case 0: COMMON(""); return to;
  263. case 1: COMMON("ntmovsb"); return to;
  264. case 2: COMMON("ntmovsw"); return to;
  265. default: COMMON("ntmovswntmovsb"); return to;
  266. }
  267. }
  268.   
  269. #undef COMMON
  270. }
  271. #define __HAVE_ARCH_MEMCPY
  272. #ifdef CONFIG_X86_USE_3DNOW
  273. #include <asm/mmx.h>
  274. /*
  275.  * This CPU favours 3DNow strongly (eg AMD Athlon)
  276.  */
  277. static inline void * __constant_memcpy3d(void * to, const void * from, size_t len)
  278. {
  279. if (len < 512)
  280. return __constant_memcpy(to, from, len);
  281. return _mmx_memcpy(to, from, len);
  282. }
  283. static __inline__ void *__memcpy3d(void *to, const void *from, size_t len)
  284. {
  285. if (len < 512)
  286. return __memcpy(to, from, len);
  287. return _mmx_memcpy(to, from, len);
  288. }
  289. #define memcpy(t, f, n) 
  290. (__builtin_constant_p(n) ? 
  291.  __constant_memcpy3d((t),(f),(n)) : 
  292.  __memcpy3d((t),(f),(n)))
  293. #else
  294. /*
  295.  * No 3D Now!
  296.  */
  297.  
  298. #define memcpy(t, f, n) 
  299. (__builtin_constant_p(n) ? 
  300.  __constant_memcpy((t),(f),(n)) : 
  301.  __memcpy((t),(f),(n)))
  302. #endif
  303. /*
  304.  * struct_cpy(x,y), copy structure *x into (matching structure) *y.
  305.  *
  306.  * We get link-time errors if the structure sizes do not match.
  307.  * There is no runtime overhead, it's all optimized away at
  308.  * compile time.
  309.  */
  310. extern void __struct_cpy_bug (void);
  311. #define struct_cpy(x,y) 
  312. ({
  313. if (sizeof(*(x)) != sizeof(*(y))) 
  314. __struct_cpy_bug;
  315. memcpy(x, y, sizeof(*(x)));
  316. })
  317. #define __HAVE_ARCH_MEMMOVE
  318. static inline void * memmove(void * dest,const void * src, size_t n)
  319. {
  320. int d0, d1, d2;
  321. if (dest<src)
  322. __asm__ __volatile__(
  323. "repnt"
  324. "movsb"
  325. : "=&c" (d0), "=&S" (d1), "=&D" (d2)
  326. :"0" (n),"1" (src),"2" (dest)
  327. : "memory");
  328. else
  329. __asm__ __volatile__(
  330. "stdnt"
  331. "repnt"
  332. "movsbnt"
  333. "cld"
  334. : "=&c" (d0), "=&S" (d1), "=&D" (d2)
  335. :"0" (n),
  336.  "1" (n-1+(const char *)src),
  337.  "2" (n-1+(char *)dest)
  338. :"memory");
  339. return dest;
  340. }
  341. #define memcmp __builtin_memcmp
  342. #define __HAVE_ARCH_MEMCHR
  343. static inline void * memchr(const void * cs,int c,size_t count)
  344. {
  345. int d0;
  346. register void * __res;
  347. if (!count)
  348. return NULL;
  349. __asm__ __volatile__(
  350. "repnent"
  351. "scasbnt"
  352. "je 1fnt"
  353. "movl $1,%0n"
  354. "1:tdecl %0"
  355. :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
  356. return __res;
  357. }
  358. static inline void * __memset_generic(void * s, char c,size_t count)
  359. {
  360. int d0, d1;
  361. __asm__ __volatile__(
  362. "repnt"
  363. "stosb"
  364. : "=&c" (d0), "=&D" (d1)
  365. :"a" (c),"1" (s),"0" (count)
  366. :"memory");
  367. return s;
  368. }
  369. /* we might want to write optimized versions of these later */
  370. #define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
  371. /*
  372.  * memset(x,0,y) is a reasonably common thing to do, so we want to fill
  373.  * things 32 bits at a time even when we don't know the size of the
  374.  * area at compile-time..
  375.  */
  376. static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
  377. {
  378. int d0, d1;
  379. __asm__ __volatile__(
  380. "rep ; stoslnt"
  381. "testb $2,%b3nt"
  382. "je 1fnt"
  383. "stoswn"
  384. "1:ttestb $1,%b3nt"
  385. "je 2fnt"
  386. "stosbn"
  387. "2:"
  388. : "=&c" (d0), "=&D" (d1)
  389. :"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
  390. :"memory");
  391. return (s);
  392. }
  393. /* Added by Gertjan van Wingerde to make minix and sysv module work */
  394. #define __HAVE_ARCH_STRNLEN
  395. static inline size_t strnlen(const char * s, size_t count)
  396. {
  397. int d0;
  398. register int __res;
  399. __asm__ __volatile__(
  400. "movl %2,%0nt"
  401. "jmp 2fn"
  402. "1:tcmpb $0,(%0)nt"
  403. "je 3fnt"
  404. "incl %0n"
  405. "2:tdecl %1nt"
  406. "cmpl $-1,%1nt"
  407. "jne 1bn"
  408. "3:tsubl %2,%0"
  409. :"=a" (__res), "=&d" (d0)
  410. :"c" (s),"1" (count));
  411. return __res;
  412. }
  413. /* end of additional stuff */
  414. #define __HAVE_ARCH_STRSTR
  415. extern char *strstr(const char *cs, const char *ct);
  416. /*
  417.  * This looks horribly ugly, but the compiler can optimize it totally,
  418.  * as we by now know that both pattern and count is constant..
  419.  */
  420. static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
  421. {
  422. switch (count) {
  423. case 0:
  424. return s;
  425. case 1:
  426. *(unsigned char *)s = pattern;
  427. return s;
  428. case 2:
  429. *(unsigned short *)s = pattern;
  430. return s;
  431. case 3:
  432. *(unsigned short *)s = pattern;
  433. *(2+(unsigned char *)s) = pattern;
  434. return s;
  435. case 4:
  436. *(unsigned long *)s = pattern;
  437. return s;
  438. }
  439. #define COMMON(x) 
  440. __asm__  __volatile__( 
  441. "rep ; stosl" 
  442. : "=&c" (d0), "=&D" (d1) 
  443. : "a" (pattern),"0" (count/4),"1" ((long) s) 
  444. : "memory")
  445. {
  446. int d0, d1;
  447. switch (count % 4) {
  448. case 0: COMMON(""); return s;
  449. case 1: COMMON("ntstosb"); return s;
  450. case 2: COMMON("ntstosw"); return s;
  451. default: COMMON("ntstoswntstosb"); return s;
  452. }
  453. }
  454.   
  455. #undef COMMON
  456. }
  457. #define __constant_c_x_memset(s, c, count) 
  458. (__builtin_constant_p(count) ? 
  459.  __constant_c_and_count_memset((s),(c),(count)) : 
  460.  __constant_c_memset((s),(c),(count)))
  461. #define __memset(s, c, count) 
  462. (__builtin_constant_p(count) ? 
  463.  __constant_count_memset((s),(c),(count)) : 
  464.  __memset_generic((s),(c),(count)))
  465. #define __HAVE_ARCH_MEMSET
  466. #define memset(s, c, count) 
  467. (__builtin_constant_p(c) ? 
  468.  __constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : 
  469.  __memset((s),(c),(count)))
  470. /*
  471.  * find the first occurrence of byte 'c', or 1 past the area if none
  472.  */
  473. #define __HAVE_ARCH_MEMSCAN
  474. static inline void * memscan(void * addr, int c, size_t size)
  475. {
  476. if (!size)
  477. return addr;
  478. __asm__("repnz; scasbnt"
  479. "jnz 1fnt"
  480. "dec %%edin"
  481. "1:"
  482. : "=D" (addr), "=c" (size)
  483. : "0" (addr), "1" (size), "a" (c));
  484. return addr;
  485. }
  486. #endif /* CONFIG_X86_USE_STRING_486 */
  487. #endif /* __KERNEL__ */
  488. #endif