#include <string.h>
#include <stdlib.h> /* malloc() */
#include <stdio.h> /* sprintf() */
#include <signal.h>
#include <errno.h>
char __attribute__ ((weak, visibility ("default"))) *strcat(char *dest, const char *src)
{
int d0, d1, d2, d3;
asm volatile ("cld\n\t"
"repne\n\t"
"scasb\n\t"
"decl %1\n"
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al, %%al\n\t"
"jne 1b"
: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
: "0" (src), "1" (dest), "2" (0), "3" (0xffffffff)
: "cc", "memory");
return dest;
}
char __attribute__ ((weak, visibility ("default"))) *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;
}
int __attribute__ ((weak, visibility ("default"))) 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;
}
char __attribute__ ((weak, visibility ("default"))) *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;
}
size_t __attribute__ ((weak, visibility ("default"))) strlen(const char *s)
{
int d0;
register 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;
}
size_t __attribute__ ((weak, visibility ("default"))) strnlen(const char *s, size_t 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;
}
char __attribute__ ((weak, visibility ("default"))) *strncat(char *dest, const char *src, size_t n)
{
int d0, d1, d2, d3;
asm volatile ("cld\n\t"
"repne\n\t"
"scasb\n\t"
"decl %1\n\t"
"movl %8, %3\n"
"1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
"stosb\n\t"
"testb %%al, %%al\n\t"
"jne 1b\n"
"2:\txorl %2, %2\n\t"
"stosb"
: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
: "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu), "g" (n)
: "cc", "memory");
return dest;
}
int __attribute__ ((weak, visibility ("default"))) strncmp(const char *s1, const char *s2, size_t 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;
}
char __attribute__ ((weak, visibility ("default"))) *strncpy(char *dest, const char *src, size_t n)
{
int d0, d1, d2, d3;
asm volatile ("cld\n"
"1:\tdecl %2\n\t"
"js 2f\n\t"
"lodsb\n\t"
"stosb\n\t"
"testb %%al, %%al\n\t"
"jne 1b\n\t"
"rep\n\t"
"stosb\n"
"2:"
: "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
: "0" (src), "1" (dest), "2" (n)
: "cc", "memory");
return dest;
}
char __attribute__ ((weak, visibility ("default"))) *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;
}
void __attribute__ ((weak, visibility ("default"))) *memcpy(void *dest, const void *src, size_t 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;
}
void __attribute__ ((weak, visibility ("default"))) *memmove(void *dest, const void *src, size_t 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;
}
int __attribute__ ((weak, visibility ("default"))) memcmp(const void *s1, const void *s2, size_t 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;
}
void __attribute__ ((weak, visibility ("default"))) *memchr(const void *s, int c, size_t 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;
}
void __attribute__ ((weak, visibility ("default"))) *memset(void *s, int c, size_t 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;
}
char __attribute__ ((weak, visibility ("default"))) *strerror(int errnum)
{
static char str[64];
if (errnum < 0 || errnum >= sys_nerr || !sys_errlist[errnum])
sprintf(str, "Unknown error %d", errnum);
else
strcpy(str, sys_errlist[errnum]);
return str;
}
char __attribute__ ((weak, visibility ("default"))) *strdup(const char *s)
{
char *d;
if (!(d = malloc(strlen(s) + 1)))
return NULL;
strcpy(d, s);
return d;
}
char __attribute__ ((weak, visibility ("default"))) *strsignal(int sig)
{
static char str[64];
if (sig < 0 || sig >= sys_nsig || !sys_siglist[sig])
sprintf(str, "Unknown signal %d", sig);
else
strcpy(str, sys_siglist[sig]);
return str;
}