0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #define __NO_FORTIFY
0015 #include <linux/string.h>
0016 #include <linux/export.h>
0017
0018 #ifdef __HAVE_ARCH_STRCPY
0019 char *strcpy(char *dest, const char *src)
0020 {
0021 int d0, d1, d2;
0022 asm volatile("1:\tlodsb\n\t"
0023 "stosb\n\t"
0024 "testb %%al,%%al\n\t"
0025 "jne 1b"
0026 : "=&S" (d0), "=&D" (d1), "=&a" (d2)
0027 : "0" (src), "1" (dest) : "memory");
0028 return dest;
0029 }
0030 EXPORT_SYMBOL(strcpy);
0031 #endif
0032
0033 #ifdef __HAVE_ARCH_STRNCPY
0034 char *strncpy(char *dest, const char *src, size_t count)
0035 {
0036 int d0, d1, d2, d3;
0037 asm volatile("1:\tdecl %2\n\t"
0038 "js 2f\n\t"
0039 "lodsb\n\t"
0040 "stosb\n\t"
0041 "testb %%al,%%al\n\t"
0042 "jne 1b\n\t"
0043 "rep\n\t"
0044 "stosb\n"
0045 "2:"
0046 : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
0047 : "0" (src), "1" (dest), "2" (count) : "memory");
0048 return dest;
0049 }
0050 EXPORT_SYMBOL(strncpy);
0051 #endif
0052
0053 #ifdef __HAVE_ARCH_STRCAT
0054 char *strcat(char *dest, const char *src)
0055 {
0056 int d0, d1, d2, d3;
0057 asm volatile("repne\n\t"
0058 "scasb\n\t"
0059 "decl %1\n"
0060 "1:\tlodsb\n\t"
0061 "stosb\n\t"
0062 "testb %%al,%%al\n\t"
0063 "jne 1b"
0064 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
0065 : "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu) : "memory");
0066 return dest;
0067 }
0068 EXPORT_SYMBOL(strcat);
0069 #endif
0070
0071 #ifdef __HAVE_ARCH_STRNCAT
0072 char *strncat(char *dest, const char *src, size_t count)
0073 {
0074 int d0, d1, d2, d3;
0075 asm volatile("repne\n\t"
0076 "scasb\n\t"
0077 "decl %1\n\t"
0078 "movl %8,%3\n"
0079 "1:\tdecl %3\n\t"
0080 "js 2f\n\t"
0081 "lodsb\n\t"
0082 "stosb\n\t"
0083 "testb %%al,%%al\n\t"
0084 "jne 1b\n"
0085 "2:\txorl %2,%2\n\t"
0086 "stosb"
0087 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
0088 : "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu), "g" (count)
0089 : "memory");
0090 return dest;
0091 }
0092 EXPORT_SYMBOL(strncat);
0093 #endif
0094
0095 #ifdef __HAVE_ARCH_STRCMP
0096 int strcmp(const char *cs, const char *ct)
0097 {
0098 int d0, d1;
0099 int res;
0100 asm volatile("1:\tlodsb\n\t"
0101 "scasb\n\t"
0102 "jne 2f\n\t"
0103 "testb %%al,%%al\n\t"
0104 "jne 1b\n\t"
0105 "xorl %%eax,%%eax\n\t"
0106 "jmp 3f\n"
0107 "2:\tsbbl %%eax,%%eax\n\t"
0108 "orb $1,%%al\n"
0109 "3:"
0110 : "=a" (res), "=&S" (d0), "=&D" (d1)
0111 : "1" (cs), "2" (ct)
0112 : "memory");
0113 return res;
0114 }
0115 EXPORT_SYMBOL(strcmp);
0116 #endif
0117
0118 #ifdef __HAVE_ARCH_STRNCMP
0119 int strncmp(const char *cs, const char *ct, size_t count)
0120 {
0121 int res;
0122 int d0, d1, d2;
0123 asm volatile("1:\tdecl %3\n\t"
0124 "js 2f\n\t"
0125 "lodsb\n\t"
0126 "scasb\n\t"
0127 "jne 3f\n\t"
0128 "testb %%al,%%al\n\t"
0129 "jne 1b\n"
0130 "2:\txorl %%eax,%%eax\n\t"
0131 "jmp 4f\n"
0132 "3:\tsbbl %%eax,%%eax\n\t"
0133 "orb $1,%%al\n"
0134 "4:"
0135 : "=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
0136 : "1" (cs), "2" (ct), "3" (count)
0137 : "memory");
0138 return res;
0139 }
0140 EXPORT_SYMBOL(strncmp);
0141 #endif
0142
0143 #ifdef __HAVE_ARCH_STRCHR
0144 char *strchr(const char *s, int c)
0145 {
0146 int d0;
0147 char *res;
0148 asm volatile("movb %%al,%%ah\n"
0149 "1:\tlodsb\n\t"
0150 "cmpb %%ah,%%al\n\t"
0151 "je 2f\n\t"
0152 "testb %%al,%%al\n\t"
0153 "jne 1b\n\t"
0154 "movl $1,%1\n"
0155 "2:\tmovl %1,%0\n\t"
0156 "decl %0"
0157 : "=a" (res), "=&S" (d0)
0158 : "1" (s), "0" (c)
0159 : "memory");
0160 return res;
0161 }
0162 EXPORT_SYMBOL(strchr);
0163 #endif
0164
0165 #ifdef __HAVE_ARCH_STRLEN
0166 size_t strlen(const char *s)
0167 {
0168 int d0;
0169 size_t res;
0170 asm volatile("repne\n\t"
0171 "scasb"
0172 : "=c" (res), "=&D" (d0)
0173 : "1" (s), "a" (0), "0" (0xffffffffu)
0174 : "memory");
0175 return ~res - 1;
0176 }
0177 EXPORT_SYMBOL(strlen);
0178 #endif
0179
0180 #ifdef __HAVE_ARCH_MEMCHR
0181 void *memchr(const void *cs, int c, size_t count)
0182 {
0183 int d0;
0184 void *res;
0185 if (!count)
0186 return NULL;
0187 asm volatile("repne\n\t"
0188 "scasb\n\t"
0189 "je 1f\n\t"
0190 "movl $1,%0\n"
0191 "1:\tdecl %0"
0192 : "=D" (res), "=&c" (d0)
0193 : "a" (c), "0" (cs), "1" (count)
0194 : "memory");
0195 return res;
0196 }
0197 EXPORT_SYMBOL(memchr);
0198 #endif
0199
0200 #ifdef __HAVE_ARCH_MEMSCAN
0201 void *memscan(void *addr, int c, size_t size)
0202 {
0203 if (!size)
0204 return addr;
0205 asm volatile("repnz; scasb\n\t"
0206 "jnz 1f\n\t"
0207 "dec %%edi\n"
0208 "1:"
0209 : "=D" (addr), "=c" (size)
0210 : "0" (addr), "1" (size), "a" (c)
0211 : "memory");
0212 return addr;
0213 }
0214 EXPORT_SYMBOL(memscan);
0215 #endif
0216
0217 #ifdef __HAVE_ARCH_STRNLEN
0218 size_t strnlen(const char *s, size_t count)
0219 {
0220 int d0;
0221 int res;
0222 asm volatile("movl %2,%0\n\t"
0223 "jmp 2f\n"
0224 "1:\tcmpb $0,(%0)\n\t"
0225 "je 3f\n\t"
0226 "incl %0\n"
0227 "2:\tdecl %1\n\t"
0228 "cmpl $-1,%1\n\t"
0229 "jne 1b\n"
0230 "3:\tsubl %2,%0"
0231 : "=a" (res), "=&d" (d0)
0232 : "c" (s), "1" (count)
0233 : "memory");
0234 return res;
0235 }
0236 EXPORT_SYMBOL(strnlen);
0237 #endif