📄 string.h
字号:
/* Optimized, inlined string functions. i486 version. Copyright (C) 1997,1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */#ifndef _STRING_H# error "Never use <bits/string.h> directly; include <string.h> instead."#endif/* The ix86 processors can access unaligned multi-byte variables. */#define _STRING_ARCH_unaligned 1/* We only provide optimizations if the user selects them and if GNU CC is used. */#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \ && defined __GNUC__ && __GNUC__ >= 2 && !__BOUNDED_POINTERS__#ifndef __STRING_INLINE# ifdef __cplusplus# define __STRING_INLINE inline# else# define __STRING_INLINE extern __inline# endif#endif/* The macros are used in some of the optimized implementations below. */#define __STRING_SMALL_GET16(src, idx) \ ((((__const unsigned char *) (src))[idx + 1] << 8) \ | ((__const unsigned char *) (src))[idx])#define __STRING_SMALL_GET32(src, idx) \ (((((__const unsigned char *) (src))[idx + 3] << 8 \ | ((__const unsigned char *) (src))[idx + 2]) << 8 \ | ((__const unsigned char *) (src))[idx + 1]) << 8 \ | ((__const unsigned char *) (src))[idx])/* Copy N bytes of SRC to DEST. */#define _HAVE_STRING_ARCH_memcpy 1#define memcpy(dest, src, n) \ (__extension__ (__builtin_constant_p (n) \ ? __memcpy_c ((dest), (src), (n)) \ : __memcpy_g ((dest), (src), (n))))#define __memcpy_c(dest, src, n) \ ((n) == 0 \ ? (dest) \ : (((n) % 4 == 0) \ ? __memcpy_by4 (dest, src, n) \ : (((n) % 2 == 0) \ ? __memcpy_by2 (dest, src, n) \ : __memcpy_g (dest, src, n))))__STRING_INLINE void *__memcpy_by4 (void *__dest, __const void *__src, size_t __n);__STRING_INLINE void *__memcpy_by4 (void *__dest, __const void *__src, size_t __n){ register unsigned long int __d0, __d1; register void *__tmp = __dest; __asm__ __volatile__ ("1:\n\t" "movl (%2),%0\n\t" "leal 4(%2),%2\n\t" "movl %0,(%1)\n\t" "leal 4(%1),%1\n\t" "decl %3\n\t" "jnz 1b" : "=&r" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1) : "1" (__tmp), "2" (__src), "3" (__n / 4) : "memory", "cc"); return __dest;}__STRING_INLINE void *__memcpy_by2 (void *__dest, __const void *__src, size_t __n);__STRING_INLINE void *__memcpy_by2 (void *__dest, __const void *__src, size_t __n){ register unsigned long int __d0, __d1; register void *__tmp = __dest; __asm__ __volatile__ ("shrl $1,%3\n\t" "jz 2f\n" /* only a word */ "1:\n\t" "movl (%2),%0\n\t" "leal 4(%2),%2\n\t" "movl %0,(%1)\n\t" "leal 4(%1),%1\n\t" "decl %3\n\t" "jnz 1b\n" "2:\n\t" "movw (%2),%w0\n\t" "movw %w0,(%1)" : "=&q" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1) : "1" (__tmp), "2" (__src), "3" (__n / 2) : "memory", "cc"); return __dest;}__STRING_INLINE void *__memcpy_g (void *__dest, __const void *__src, size_t __n);__STRING_INLINE void *__memcpy_g (void *__dest, __const void *__src, size_t __n){ register unsigned long int __d0, __d1, __d2; register void *__tmp = __dest; __asm__ __volatile__ ("cld\n\t" "shrl $1,%%ecx\n\t" "jnc 1f\n\t" "movsb\n" "1:\n\t" "shrl $1,%%ecx\n\t" "jnc 2f\n\t" "movsw\n" "2:\n\t" "rep; movsl" : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2), "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest) : "0" (__n), "1" (__tmp), "2" (__src), "m" ( *(struct { __extension__ char __x[__n]; } *)__src) : "cc"); return __dest;}#define _HAVE_STRING_ARCH_memmove 1#ifndef _FORCE_INLINES/* Copy N bytes of SRC to DEST, guaranteeing correct behavior for overlapping strings. */__STRING_INLINE void *memmove (void *__dest, __const void *__src, size_t __n){ register unsigned long int __d0, __d1, __d2; register void *__tmp = __dest; if (__dest < __src) __asm__ __volatile__ ("cld\n\t" "rep; movsb" : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest) : "0" (__n), "1" (__src), "2" (__tmp), "m" ( *(struct { __extension__ char __x[__n]; } *)__src)); else __asm__ __volatile__ ("std\n\t" "rep; movsb\n\t" "cld" : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest) : "0" (__n), "1" (__n - 1 + (__const char *) __src), "2" (__n - 1 + (char *) __tmp), "m" ( *(struct { __extension__ char __x[__n]; } *)__src)); return __dest;}#endif/* Compare N bytes of S1 and S2. */#define _HAVE_STRING_ARCH_memcmp 1#ifndef _FORCE_INLINES# ifndef __PIC__/* gcc has problems to spill registers when using PIC. */__STRING_INLINE intmemcmp (__const void *__s1, __const void *__s2, size_t __n){ register unsigned long int __d0, __d1, __d2; register int __res; __asm__ __volatile__ ("cld\n\t" "testl %3,%3\n\t" "repe; cmpsb\n\t" "je 1f\n\t" "sbbl %0,%0\n\t" "orl $1,%0\n" "1:" : "=&a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2) : "0" (0), "1" (__s1), "2" (__s2), "3" (__n), "m" ( *(struct { __extension__ char __x[__n]; } *)__s1), "m" ( *(struct { __extension__ char __x[__n]; } *)__s2) : "cc"); return __res;}# endif#endif/* Set N bytes of S to C. */#define _HAVE_STRING_ARCH_memset 1#define _USE_STRING_ARCH_memset 1#define memset(s, c, n) \ (__extension__ (__builtin_constant_p (n) && (n) <= 16 \ ? ((n) == 1 \ ? __memset_c1 ((s), (c)) \ : __memset_gc ((s), (c), (n))) \ : (__builtin_constant_p (c) \ ? (__builtin_constant_p (n) \ ? __memset_ccn ((s), (c), (n)) \ : memset ((s), (c), (n))) \ : (__builtin_constant_p (n) \ ? __memset_gcn ((s), (c), (n)) \ : memset ((s), (c), (n))))))#define __memset_c1(s, c) ({ void *__s = (s); \ *((unsigned char *) __s) = (unsigned char) (c); \ __s; })#define __memset_gc(s, c, n) \ ({ void *__s = (s); \ union { \ unsigned int __ui; \ unsigned short int __usi; \ unsigned char __uc; \ } *__u = __s; \ unsigned int __c = ((unsigned int) ((unsigned char) (c))) * 0x01010101; \ \ /* We apply a trick here. `gcc' would implement the following \ assignments using immediate operands. But this uses to much \ memory (7, instead of 4 bytes). So we force the value in a \ registers. */ \ if ((n) == 3 || (n) >= 5) \ __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c)); \ \ /* This `switch' statement will be removed at compile-time. */ \ switch (n) \ { \ case 15: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 11: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 7: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 3: \ __u->__usi = (unsigned short int) __c; \ __u = __extension__ ((void *) __u + 2); \ __u->__uc = (unsigned char) __c; \ break; \ \ case 14: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 10: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 6: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 2: \ __u->__usi = (unsigned short int) __c; \ break; \ \ case 13: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 9: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 5: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 1: \ __u->__uc = (unsigned char) __c; \ break; \ \ case 16: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 12: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 8: \ __u->__ui = __c; \ __u = __extension__ ((void *) __u + 4); \ case 4: \ __u->__ui = __c; \ case 0: \ break; \ } \ \ __s; })#define __memset_ccn(s, c, n) \ (((n) % 4 == 0) \ ? __memset_ccn_by4 (s, ((unsigned int) ((unsigned char) (c))) * 0x01010101,\ n) \ : (((n) % 2 == 0) \ ? __memset_ccn_by2 (s, \ ((unsigned int) ((unsigned char) (c))) * 0x01010101,\ n) \ : memset (s, c, n)))__STRING_INLINE void *__memset_ccn_by4 (void *__s, unsigned int __c, size_t __n);__STRING_INLINE void *__memset_ccn_by4 (void *__s, unsigned int __c, size_t __n){ register void *__tmp = __s; register unsigned long int __d0;#ifdef __i686__ __asm__ __volatile__ ("cld\n\t" "rep; stosl" : "=&a" (__c), "=&D" (__tmp), "=&c" (__d0), "=m" ( *(struct { __extension__ char __x[__n]; } *)__s) : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4) : "cc");#else __asm__ __volatile__ ("1:\n\t" "movl %0,(%1)\n\t" "addl $4,%1\n\t" "decl %2\n\t" "jnz 1b\n" : "=&r" (__c), "=&r" (__tmp), "=&r" (__d0), "=m" ( *(struct { __extension__ char __x[__n]; } *)__s) : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4) : "cc");#endif return __s;}__STRING_INLINE void *__memset_ccn_by2 (void *__s, unsigned int __c, size_t __n);__STRING_INLINE void *__memset_ccn_by2 (void *__s, unsigned int __c, size_t __n){ register unsigned long int __d0, __d1; register void *__tmp = __s;#ifdef __i686__ __asm__ __volatile__ ("cld\n\t" "rep; stosl\n" "stosw" : "=&a" (__d0), "=&D" (__tmp), "=&c" (__d1), "=m" ( *(struct { __extension__ char __x[__n]; } *)__s) : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4) : "cc");#else __asm__ __volatile__ ("1:\tmovl %0,(%1)\n\t" "leal 4(%1),%1\n\t" "decl %2\n\t" "jnz 1b\n" "movw %w0,(%1)" : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1), "=m" ( *(struct { __extension__ char __x[__n]; } *)__s) : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4) : "cc");#endif return __s;}#define __memset_gcn(s, c, n) \ (((n) % 4 == 0) \ ? __memset_gcn_by4 (s, c, n) \ : (((n) % 2 == 0) \ ? __memset_gcn_by2 (s, c, n) \ : memset (s, c, n)))__STRING_INLINE void *__memset_gcn_by4 (void *__s, int __c, size_t __n);__STRING_INLINE void *__memset_gcn_by4 (void *__s, int __c, size_t __n){ register void *__tmp = __s; register unsigned long int __d0; __asm__ __volatile__ ("movb %b0,%h0\n" "pushw %w0\n\t" "shll $16,%0\n\t" "popw %w0\n" "1:\n\t" "movl %0,(%1)\n\t" "addl $4,%1\n\t" "decl %2\n\t" "jnz 1b\n" : "=&q" (__c), "=&r" (__tmp), "=&r" (__d0), "=m" ( *(struct { __extension__ char __x[__n]; } *)__s) : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4) : "cc"); return __s;}__STRING_INLINE void *__memset_gcn_by2 (void *__s, int __c, size_t __n);__STRING_INLINE void *__memset_gcn_by2 (void *__s, int __c, size_t __n){ register unsigned long int __d0, __d1; register void *__tmp = __s; __asm__ __volatile__ ("movb %b0,%h0\n\t" "pushw %w0\n\t" "shll $16,%0\n\t" "popw %w0\n" "1:\n\t" "movl %0,(%1)\n\t" "leal 4(%1),%1\n\t" "decl %2\n\t" "jnz 1b\n" "movw %w0,(%1)" : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1), "=m" ( *(struct { __extension__ char __x[__n]; } *)__s) : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4) : "cc"); return __s;}/* Search N bytes of S for C. */#define _HAVE_STRING_ARCH_memchr 1#ifndef _FORCE_INLINES__STRING_INLINE void *memchr (__const void *__s, int __c, size_t __n){ register unsigned long int __d0;#ifdef __i686__ register unsigned long int __d1;#endif register unsigned char *__res; if (__n == 0) return NULL;#ifdef __i686__ __asm__ __volatile__ ("cld\n\t" "repne; scasb\n\t" "cmovne %2,%0" : "=D" (__res), "=&c" (__d0), "=&r" (__d1) : "a" (__c), "0" (__s), "1" (__n), "2" (1), "m" ( *(struct { __extension__ char __x[__n]; } *)__s) : "cc");#else __asm__ __volatile__ ("cld\n\t" "repne; scasb\n\t" "je 1f\n\t" "movl $1,%0\n" "1:" : "=D" (__res), "=&c" (__d0) : "a" (__c), "0" (__s), "1" (__n), "m" ( *(struct { __extension__ char __x[__n]; } *)__s) : "cc");#endif return __res - 1;}#endif#define _HAVE_STRING_ARCH_memrchr 1#ifndef _FORCE_INLINES__STRING_INLINE void *__memrchr (__const void *__s, int __c, size_t __n);__STRING_INLINE void *__memrchr (__const void *__s, int __c, size_t __n){ register unsigned long int __d0;# ifdef __i686__ register unsigned long int __d1;# endif register void *__res; if (__n == 0) return NULL;# ifdef __i686__ __asm__ __volatile__ ("std\n\t" "repne; scasb\n\t" "cmovne %2,%0\n\t" "cld" : "=D" (__res), "=&c" (__d0), "=&r" (__d1) : "a" (__c), "0" (__s + __n - 1), "1" (__n), "2" (-1), "m" ( *(struct { __extension__ char __x[__n]; } *)__s) : "cc");# else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -