This is the mail archive of the
cygwin-patches
mailing list for the Cygwin project.
[patch cygwin]: Replace inline-assembler in string.h by C implementation
- From: Kai Tietz <ktietz70 at googlemail dot com>
- To: cygwin-patches at cygwin dot com
- Cc: Corinna Vinschen <corinna at vinschen dot de>
- Date: Wed, 24 Oct 2012 11:16:58 +0200
- Subject: [patch cygwin]: Replace inline-assembler in string.h by C implementation
Hello,
this patch replaces the inline-assember used in string.h by C implementation.
There are three reasons why I want to suggest this. First, the C-code might
be optimized further by fixed (constant) arguments. Secondly, it is
architecture
independent and so we just need to maintain on code-path. And as
third point, by
inspecting generated assembly code produced by compiler out of C code
vs. inline-assembler
it shows that compiler produces better code. It handles
jump-threading better, and also
improves average executed instructions.
ChangeLog
2012-10-24 Kai Tietz
* string.h (strechr): Replace assembler by
C code.
(ascii_strcasematch): Likewise.
(ascii_strncasematch): Likwise.
Ok for apply?
Regards,
Kai
Index: string.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/string.h,v
retrieving revision 1.14
diff -p -u -r1.14 string.h
--- string.h 19 Jan 2011 09:41:54 -0000 1.14
+++ string.h 24 Oct 2012 09:10:27 -0000
@@ -22,20 +22,9 @@ extern "C" {
static inline __stdcall char *
strechr (const char *s, int c)
{
- register char * res;
- __asm__ __volatile__ ("\
- movb %%al,%%ah\n\
-1: movb (%1),%%al\n\
- cmpb %%ah,%%al\n\
- je 2f\n\
- incl %1\n\
- testb %%al,%%al\n\
- jne 1b\n\
- decl %1\n\
-2: movl %1,%0\n\
- ":"=a" (res), "=r" (s)
- :"0" (c), "1" (s));
- return res;
+ while (*s != (char) c && *s != 0)
+ ++s;
+ return (char *) s;
}
#ifdef __INSIDE_CYGWIN__
@@ -45,57 +34,38 @@ extern const char isalpha_array[];
static inline int
ascii_strcasematch (const char *cs, const char *ct)
{
- register int __res;
- int d0, d1;
- __asm__ ("\
- .global _isalpha_array \n\
- cld \n\
- andl $0xff,%%eax \n\
-1: lodsb \n\
- scasb \n\
- je 2f \n\
- xorb _isalpha_array(%%eax),%%al \n\
- cmpb -1(%%edi),%%al \n\
- jne 3f \n\
-2: testb %%al,%%al \n\
- jnz 1b \n\
- movl $1,%%eax \n\
- jmp 4f \n\
-3: xor %0,%0 \n\
-4:"
- :"=a" (__res), "=&S" (d0), "=&D" (d1)
- : "1" (cs), "2" (ct));
+ register const unsigned char *us, *ut;
- return __res;
+ us = (const unsigned char *) cs;
+ ut = (const unsigned char *) ct;
+
+ while (us[0] == ut[0] || (us[0] ^ isalpha_array[us[0]]) == ut[0])
+ {
+ if (us[0] == 0)
+ return 1;
+ ++us, ++ut;
+ }
+ return 0;
}
static inline int
ascii_strncasematch (const char *cs, const char *ct, size_t n)
{
- register int __res;
- int d0, d1, d2;
- __asm__ ("\
- .global _isalpha_array; \n\
- cld \n\
- andl $0xff,%%eax \n\
-1: decl %3 \n\
- js 3f \n\
- lodsb \n\
- scasb \n\
- je 2f \n\
- xorb _isalpha_array(%%eax),%%al \n\
- cmpb -1(%%edi),%%al \n\
- jne 4f \n\
-2: testb %%al,%%al \n\
- jnz 1b \n\
-3: movl $1,%%eax \n\
- jmp 5f \n\
-4: xor %0,%0 \n\
-5:"
- :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
- :"1" (cs), "2" (ct), "3" (n));
+ register const unsigned char *us, *ut;
- return __res;
+ if (!n)
+ return 1;
+ us = (const unsigned char *) cs;
+ ut = (const unsigned char *) ct;
+
+ while (us[0] == ut[0] || (us[0] ^ isalpha_array[us[0]]) == ut[0])
+ {
+ --n;
+ if (!n || us[0] == 0)
+ return 1;
+ ++us, ++ut;
+ }
+ return 0;
}
#undef strcasecmp