diff options
Diffstat (limited to 'src/kvilib/core/kvi_strasm.h')
-rw-r--r-- | src/kvilib/core/kvi_strasm.h | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/kvilib/core/kvi_strasm.h b/src/kvilib/core/kvi_strasm.h new file mode 100644 index 00000000..5d3b19ca --- /dev/null +++ b/src/kvilib/core/kvi_strasm.h @@ -0,0 +1,194 @@ +#ifndef _KVI_STRASM_H_ +#define _KVI_STRASM_H_ + +//============================================================================= +// +// File : kvi_strasm.h +// Creation date : Sun Jun 18 2000 18:38:26 by Szymon Stefanek +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 2 +// of the License, or (at your opinion) 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, write to the Free Software Foundation, +// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +//============================================================================= +// +// Inline assembly implementations of the commonly used string functions +// These will work only on i386 based machines and can be compiled +// only by gcc +// +//============================================================================= + +extern inline bool kvi_strEqualCS(const char * str1,const char * str2) +{ + // An instruction pattern is really useful in this case. + // When inlining, GCC can optimize to load esi and edi + // directly with the strings , without pushing and getting it + // from the stack... + register bool eax; + __asm__ __volatile__ ( + " cld\n" + "1:\n" + " lodsb %%ds:(%%esi),%%al\n" + " scasb %%es:(%%edi),%%al\n" + " jne 2f\n" + " testb %%al,%%al\n" + " jne 1b\n" + " movl $0x1,%%eax\n" + " jmp 3f\n" + "2:\n" + " xorl %%eax,%%eax\n" + "3:" + : "=a" (eax), "=&S" (str1), "=&D" (str2) + : "1" (str1), "2" (str2) + ); + return eax; +} + +extern inline bool kvi_strEqualCSN(const char * str1,const char * str2,int len) +{ + register bool eax; + __asm__ __volatile__ ( + "1:\n" + " decl %3\n" + " js 2f\n" + " movb (%1),%%al\n" + " incl %1\n" + " cmpb %%al,(%2)\n" + " jne 3f\n" + " incl %2\n" + " testb %%al,%%al\n" + " jne 1b\n" + "2:\n" + " movl $0x1,%%eax\n" + " jmp 4f\n" + "3:\n" + " xorl %%eax,%%eax\n" + "4:\n" + : "=a" (eax), "=r" (str1), "=r" (str2), "=r" (len) + : "1" (str1), "2" (str2), "3" (len) + ); + return eax; +} + +// OPTIMIZATION +// The following two functions are used to compare a variable string with one in that +// only A-Z<->a-z case insensivity is significant. +// For example +// kvi_strEqualNoLocalCI("a string that does not contain any strange char",str2) +// will always give the correct result +// These will NOT work with localizable characters: +// 'a' with umlaut will be not equal to 'A' with umlaut + +extern inline bool kvi_strEqualNoLocaleCI(const char *str1,const char *str2) +{ + // Trivial implementation + // Ignores completely locales....only A-Z chars are transformed to a-z + // Anyway...it will work for IRC :) + register int reg; + register bool eax; + __asm__ __volatile__ ( + "1:\n" + " movb (%2),%%al\n" + " cmpb $65,%%al\n" + " jb 2f\n" + " cmpb $90,%%al\n" + " ja 2f\n" + " addb $32,%%al\n" + "2:\n" + " movb (%3),%b1\n" + " cmpb $65,%b1\n" + " jb 3f\n" + " cmpb $90,%b1\n" + " ja 3f\n" + " addb $32,%b1\n" + "3:\n" + " cmpb %%al,%b1\n" + " jne 4f\n" + " incl %2\n" + " incl %3\n" + " testb %%al,%%al\n" + " jne 1b\n" + " movl $1,%%eax\n" + " jmp 5f\n" + "4:\n" + " xorl %%eax,%%eax\n" + "5:\n" + : "=a" (eax), "=q" (reg), "=r" (str1), "=r" (str2) + : "2" (str1), "3" (str2) + ); + return eax; +} + +extern inline bool kvi_strEqualNoLocaleCIN(const char *str1,const char *str2,int len) +{ + + register int reg; + register bool eax; + __asm__ __volatile__ ( + "1:\n" + " decl %4\n" + " js 4f\n" + " movb (%2),%%al\n" + " cmpb $65,%%al\n" + " jb 2f\n" + " cmpb $90,%%al\n" + " ja 2f\n" + " addb $32,%%al\n" + "2:\n" + " movb (%3),%b1\n" + " cmpb $65,%b1\n" + " jb 3f\n" + " cmpb $90,%b1\n" + " ja 3f\n" + " addb $32,%b1\n" + "3:\n" + " cmpb %%al,%b1\n" + " jne 5f\n" + " incl %2\n" + " incl %3\n" + " testb %%al,%%al\n" + " jne 1b\n" + "4:\n" + " movl $1,%%eax\n" + " jmp 6f\n" + "5:\n" + " xorl %%eax,%%eax\n" + "6:\n" + : "=a" (eax), "=q" (reg), "=r" (str1), "=r" (str2), "=r" (len) + : "2" (str1), "3" (str2), "4" (len) + ); + return eax; +} + + +extern inline int kvi_strLen(const char * str) +{ + register int ecx; + __asm__ __volatile__( + " cld\n" + " repne\n" + " scasb\n" + " notl %0\n" + " decl %0" + : "=c" (ecx), "=&D" (str) + : "0" (0xffffffff), "1" (str), "a" (0) + ); + return ecx; +} + +#endif //_KVI_STRASM_H_ |