#ifndef _STRING_H
#define _STRING_H
#ifdef STRING_C
#define inline
#endif
extern inline unsigned int strlen(const char *s)
{
int d0;
register unsigned int res;
asm ("cld\n\t"
"repne\n\t"
"scasb\n\t"
"notl %0\n\t"
"decl %0"
: "=c" (res), "=&D" (d0)
: "1" (s), "a" (0), "0" (0xffffffff)
: "cc");
return res;
}
extern inline unsigned int strnlen(const char *s, unsigned int n)
{
int d0, d1, d2;
register unsigned int res;
asm ("cld\n"
"1:\tdecl %5\n\t"
"js 2f\n\t"
"scasb\n\t"
"je 2f\n\t"
"incl %6\n\t"
"jmp 1b\n\t"
"2:"
: "=q" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
: "2" (s), "1" (n), "0" (0), "3" (0)
: "cc");
return res;
}
extern inline void *memcpy(void *dest, const void *src, unsigned int n)
{
int d0, d1, d2;
asm volatile ("cld\n\t"
"rep\n\t"
"movsl\n\t"
"testb $2, %b4\n\t"
"je 1f\n\t"
"movsw\n"
"1:\ttestb $1, %b4\n\t"
"je 2f\n\t"
"movsb\n"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n / 4), "q" (n), "1" (dest), "2" (src)
: "cc", "memory");
return dest;
}
extern inline void *memmove(void *dest, const void *src, unsigned int n)
{
int d0, d1, d2;
if (dest < src)
asm volatile ("cld\n\t"
"rep\n\t"
"movsb\n\t"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n), "1" (dest), "2" (src)
: "cc", "memory");
else
asm volatile ("std\n\t"
"rep\n\t"
"movsb\n\t"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n), "1" (dest + n - 1), "2" (src + n - 1)
: "cc", "memory");
return dest;
}
extern inline int memcmp(const void *s1, const void *s2, unsigned int n)
{
int d0, d1, d2;
register int res;
asm ("cld\n\t"
"repe\n\t"
"cmpsb\n\t"
"je 1f\n\t"
"movl $1, %%eax\n\t"
"jl 1f\n\t"
"negl %%eax\n"
"1:"
: "=a" (res), "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (0), "1" (n), "2" (s1), "3" (s2)
: "cc");
return res;
}
extern inline void *memchr(const void *s, char c, unsigned int n)
{
int d0;
register void *res;
asm ("cld\n\t"
"repne\n\t"
"scasb\n\t"
"je 1f\n\t"
"movl $1, %0\n"
"1:\tdecl %0"
: "=D" (res), "=&c" (d0)
: "a" (c), "1" (n), "0" (s)
: "cc");
return res;
}
extern inline void *memset(void *s, int c, unsigned int n)
{
int d0, d1;
asm volatile ("cld\n\t"
"rep\n\t"
"stosb"
: "=&c" (d0), "=&D" (d1)
: "a" (c), "1" (s), "0" (n)
: "cc", "memory");
return s;
}
extern inline char *strcpy(char *dest, const char *src)
{
int d0, d1, d2;
asm volatile ("cld\n"
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al, %%al\n\t"
"jne 1b"
: "=&S" (d0), "=&D" (d1), "=&a" (d2)
: "0" (src), "1" (dest)
: "cc", "memory");
return dest;
}
extern inline int strcmp(const char *s1, const char *s2)
{
int d0, d1;
register int res;
asm ("cld\n"
"1:\tlodsb\n\t"
"scasb\n\t"
"jne 2f\n\t"
"testb %%al, %%al\n\t"
"jne 1b\n\t"
"xorl %%eax, %%eax\n\t"
"jmp 3f\n"
"2:\tsbbl %%eax, %%eax\n\t"
"orb $1, %%al\n"
"3:"
: "=a" (res), "=&S" (d0), "=&D" (d1)
: "1" (s1), "2" (s2)
: "cc");
return res;
}
extern inline int strncmp(const char *s1, const char *s2, unsigned int n)
{
int d0, d1, d2;
register int res;
asm ("cld\n"
"1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
"scasb\n\t"
"jne 3f\n\t"
"testb %%al, %%al\n\t"
"jne 1b\n"
"2:\txorl %%eax, %%eax\n\t"
"jmp 4f\n"
"3:\tsbbl %%eax, %%eax\n\t"
"orb $1, %%al\n"
"4:"
: "=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
: "1" (s2), "2" (s1), "3" (n)
: "cc");
return res;
}
extern inline char *strchr(const char *s, int c)
{
int d0;
register char *res;
asm ("cld\n\t"
"movb %%al, %%ah\n"
"1:\tlodsb\n\t"
"cmpb %%ah, %%al\n\t"
"je 2f\n\t"
"testb %%al, %%al\n\t"
"jne 1b\n\t"
"movl $1, %1\n"
"2:\tmovl %1, %0\n\t"
"decl %0"
: "=a" (res), "=&S" (d0)
: "1" (s), "0" (c)
: "cc");
return res;
}
extern inline char *strrchr(const char *s, int c)
{
int d0, d1;
register char *res;
asm ("cld\n\t"
"movb %%al, %%ah\n"
"1:\tlodsb\n\t"
"cmpb %%ah, %%al\n\t"
"jne 2f\n\t"
"leal -1(%%esi), %0\n"
"2:\ttestb %%al, %%al\n\t"
"jne 1b"
: "=g" (res), "=&S" (d0), "=&a" (d1)
: "0" (0), "1" (s), "2" (c)
: "cc");
return res;
}
#undef inline
#endif