/* 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 . */ #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