/* Copyright (C) 2008 Emmanuel Varoquaux This file is part of XOS. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include /* malloc() */ #include /* sprintf() */ #include #include 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; }