1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

Fix signedness in wcscmp comparison

This commit is contained in:
Liubov Dmitrieva
2011-10-23 13:34:15 -04:00
committed by Ulrich Drepper
parent 774a2669af
commit 95584d3b33
5 changed files with 239 additions and 132 deletions

View File

@ -1,3 +1,14 @@
2011-09-22 Liubov Dmitrieva <liubov.dmitrieva@gmail.com>
* sysdeps/x86_64/wcscmp.S: Update.
Fix wrong comparison semantics.
wcscmp shall use signed comparison not unsigned.
Don't use substraction to avoid overflow bug.
* sysdeps/i386/i686/multiarch/wcscmp-sse2.S: Likewise.
* wcsmbc/wcscmp.c: Likewise.
* string/test-strcmp.c: Likewise.
Add new tests to check cases with negative values.
2011-10-23 Ulrich Drepper <drepper@gmail.com> 2011-10-23 Ulrich Drepper <drepper@gmail.com>
* sysdeps/ieee754/dbl-64/dla.h: Move DLA_FMA definition to... * sysdeps/ieee754/dbl-64/dla.h: Move DLA_FMA definition to...

View File

@ -1,4 +1,4 @@
/* Test and measure STRCMP functions. /* Test and measure strcmp and wcscmp functions.
Copyright (C) 1999, 2002, 2003, 2005, 2011 Free Software Foundation, Inc. Copyright (C) 1999, 2002, 2003, 2005, 2011 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999. Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@ -23,7 +23,6 @@
#include "test-string.h" #include "test-string.h"
#ifdef WIDE #ifdef WIDE
# include <inttypes.h>
# include <wchar.h> # include <wchar.h>
# define L(str) L##str # define L(str) L##str
@ -34,12 +33,53 @@
# define SIMPLE_STRCMP simple_wcscmp # define SIMPLE_STRCMP simple_wcscmp
# define STUPID_STRCMP stupid_wcscmp # define STUPID_STRCMP stupid_wcscmp
# define CHAR wchar_t # define CHAR wchar_t
# define UCHAR uint32_t # define UCHAR wchar_t
# define CHARBYTES 4 # define CHARBYTES 4
# define CHARBYTESLOG 2 # define CHARBYTESLOG 2
# define CHARALIGN __alignof__ (CHAR) # define CHARALIGN __alignof__ (CHAR)
# define MIDCHAR 0x7fffffff # define MIDCHAR 0x7fffffff
# define LARGECHAR 0xfffffffe # define LARGECHAR 0xfffffffe
# define CHAR__MAX WCHAR_MAX
# define CHAR__MIN WCHAR_MIN
/* Wcscmp uses signed semantics for comparison, not unsigned */
/* Avoid using substraction since possible overflow */
int
simple_wcscmp (const wchar_t *s1, const wchar_t *s2)
{
wchar_t c1, c2;
do
{
c1 = *s1++;
c2 = *s2++;
if (c2 == L'\0')
return c1 - c2;
}
while (c1 == c2);
return c1 < c2 ? -1 : 1;
}
int
stupid_wcscmp (const wchar_t *s1, const wchar_t *s2)
{
size_t ns1 = wcslen (s1) + 1;
size_t ns2 = wcslen (s2) + 1;
size_t n = ns1 < ns2 ? ns1 : ns2;
int ret = 0;
wchar_t c1, c2;
while (n--) {
c1 = *s1++;
c2 = *s2++;
if ((ret = c1 < c2 ? -1 : c1 == c2 ? 0 : 1) != 0)
break;
}
return ret;
}
#else #else
# define L(str) str # define L(str) str
# define STRCMP strcmp # define STRCMP strcmp
@ -55,31 +95,35 @@
# define CHARALIGN 1 # define CHARALIGN 1
# define MIDCHAR 0x7f # define MIDCHAR 0x7f
# define LARGECHAR 0xfe # define LARGECHAR 0xfe
#endif # define CHAR__MAX CHAR_MAX
typedef int (*proto_t) (const CHAR *, const CHAR *); # define CHAR__MIN CHAR_MIN
/* Strcmp uses unsigned semantics for comparison. */
int int
SIMPLE_STRCMP (const CHAR *s1, const CHAR *s2) simple_strcmp (const char *s1, const char *s2)
{ {
int ret; int ret;
while ((ret = *(UCHAR *) s1 - *(UCHAR *) s2++) == 0 && *s1++); while ((ret = *(unsigned char *) s1 - *(unsigned char*) s2++) == 0 && *s1++);
return ret; return ret;
} }
int int
STUPID_STRCMP (const CHAR *s1, const CHAR *s2) stupid_strcmp (const char *s1, const char *s2)
{ {
size_t ns1 = STRLEN (s1) + 1; size_t ns1 = strlen (s1) + 1;
size_t ns2 = STRLEN (s2) + 1; size_t ns2 = strlen (s2) + 1;
size_t n = ns1 < ns2 ? ns1 : ns2; size_t n = ns1 < ns2 ? ns1 : ns2;
int ret = 0; int ret = 0;
while (n--) while (n--)
if ((ret = *(UCHAR *) s1++ - *(UCHAR *) s2++) != 0) if ((ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) != 0)
break; break;
return ret; return ret;
} }
#endif
typedef int (*proto_t) (const CHAR *, const CHAR *);
IMPL (STUPID_STRCMP, 1) IMPL (STUPID_STRCMP, 1)
IMPL (SIMPLE_STRCMP, 1) IMPL (SIMPLE_STRCMP, 1)
@ -276,14 +320,31 @@ check (void)
STRCPY(s1, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs")); STRCPY(s1, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs"));
STRCPY(s2, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV")); STRCPY(s2, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV"));
/* Check correct working for negatives values */
s1[0] = 1;
s2[0] = 1;
s1[1] = 1;
s2[1] = 1;
s1[2] = -1;
s2[2] = 3;
s1[3] = 0;
s2[3] = -1;
/* Check possible overflow bug, actual more for wcscmp */
s1[7] = CHAR__MIN;
s2[7] = CHAR__MAX;
size_t l1 = STRLEN (s1); size_t l1 = STRLEN (s1);
size_t l2 = STRLEN (s2); size_t l2 = STRLEN (s2);
for (size_t i1 = 0; i1 < l1; i1++) for (size_t i1 = 0; i1 < l1; i1++)
for (size_t i2 = 0; i2 < l2; i2++) for (size_t i2 = 0; i2 < l2; i2++)
{ {
int exp_result = SIMPLE_STRCMP (s1 + i1, s2 + i2); int exp_result = SIMPLE_STRCMP (s1 + i1, s2 + i2);
FOR_EACH_IMPL (impl, 0) FOR_EACH_IMPL (impl, 0)
check_result (impl, s1 + i1, s2 + i2, exp_result); check_result (impl, s1 + i1, s2 + i2, exp_result);
} }
} }

View File

@ -21,7 +21,6 @@
#ifndef NOT_IN_libc #ifndef NOT_IN_libc
# include <sysdep.h> # include <sysdep.h>
# include "asm-syntax.h"
# define CFI_PUSH(REG) \ # define CFI_PUSH(REG) \
cfi_adjust_cfa_offset (4); \ cfi_adjust_cfa_offset (4); \
@ -34,18 +33,16 @@
# define PUSH(REG) pushl REG; CFI_PUSH (REG) # define PUSH(REG) pushl REG; CFI_PUSH (REG)
# define POP(REG) popl REG; CFI_POP (REG) # define POP(REG) popl REG; CFI_POP (REG)
# ifndef STRCMP
# define STRCMP __wcscmp_sse2
# endif
# define ENTRANCE PUSH(%esi); PUSH(%edi) # define ENTRANCE PUSH(%esi); PUSH(%edi)
# define RETURN POP(%edi); POP(%esi); ret; CFI_PUSH(%esi); CFI_PUSH(%edi); # define RETURN POP(%edi); POP(%esi); ret; CFI_PUSH(%esi); CFI_PUSH(%edi);
# define PARMS 4 # define PARMS 4
# define STR1 PARMS # define STR1 PARMS
# define STR2 STR1+4 # define STR2 STR1+4
/* Note: wcscmp uses signed comparison, not unsugned as in strcmp function. */
.text .text
ENTRY (STRCMP) ENTRY (__wcscmp_sse2)
/* /*
* This implementation uses SSE to compare up to 16 bytes at a time. * This implementation uses SSE to compare up to 16 bytes at a time.
*/ */
@ -264,20 +261,20 @@ L(continue_00_48):
test %ecx, %ecx test %ecx, %ecx
jnz L(less4_double_words1) jnz L(less4_double_words1)
sub (%esi), %eax cmp (%esi), %eax
jnz L(return) jne L(nequal)
mov 4(%edi), %eax mov 4(%edi), %eax
sub 4(%esi), %eax cmp 4(%esi), %eax
jnz L(return) jne L(nequal)
mov 8(%edi), %eax mov 8(%edi), %eax
sub 8(%esi), %eax cmp 8(%esi), %eax
jnz L(return) jne L(nequal)
mov 12(%edi), %eax mov 12(%edi), %eax
sub 12(%esi), %eax cmp 12(%esi), %eax
jnz L(return) jne L(nequal)
movdqu 16(%esi), %xmm2 movdqu 16(%esi), %xmm2
pcmpeqd %xmm2, %xmm0 /* Any null double_word? */ pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
@ -381,7 +378,7 @@ L(continue_32_48):
movdqu 48(%esi), %xmm2 movdqu 48(%esi), %xmm2
pcmpeqd %xmm1, %xmm0 /* Any null double_word? */ pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */ pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
psubb %xmm0, %xmm1 /* packed sub of comparison results*/ psubb %xmm0, %xmm1 /* packed sub of comparison results */
pmovmskb %xmm1, %edx pmovmskb %xmm1, %edx
sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */ sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
jnz L(less4_double_words_48) jnz L(less4_double_words_48)
@ -585,20 +582,20 @@ L(continue_48_00):
test %ecx, %ecx test %ecx, %ecx
jnz L(less4_double_words1) jnz L(less4_double_words1)
sub (%esi), %eax cmp (%esi), %eax
jnz L(return) jne L(nequal)
mov 4(%edi), %eax mov 4(%edi), %eax
sub 4(%esi), %eax cmp 4(%esi), %eax
jnz L(return) jne L(nequal)
mov 8(%edi), %eax mov 8(%edi), %eax
sub 8(%esi), %eax cmp 8(%esi), %eax
jnz L(return) jne L(nequal)
mov 12(%edi), %eax mov 12(%edi), %eax
sub 12(%esi), %eax cmp 12(%esi), %eax
jnz L(return) jne L(nequal)
movdqu 16(%edi), %xmm1 movdqu 16(%edi), %xmm1
pcmpeqd %xmm1, %xmm0 /* Any null double_word? */ pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
@ -839,142 +836,161 @@ L(less4_double_words1):
test %ecx, %ecx test %ecx, %ecx
jz L(equal) jz L(equal)
mov 12(%esi), %edx mov 12(%esi), %ecx
mov 12(%edi), %eax cmp %ecx, 12(%edi)
sub %edx, %eax jne L(nequal)
xor %eax, %eax
RETURN RETURN
.p2align 4 .p2align 4
L(less4_double_words): L(less4_double_words):
xor %eax, %eax
test %dl, %dl test %dl, %dl
jz L(next_two_double_words) jz L(next_two_double_words)
and $15, %dl and $15, %dl
jz L(second_double_word) jz L(second_double_word)
mov (%edi), %eax mov (%esi), %ecx
sub (%esi), %eax cmp %ecx, (%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(second_double_word): L(second_double_word):
mov 4(%edi), %eax mov 4(%esi), %ecx
sub 4(%esi), %eax cmp %ecx, 4(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(next_two_double_words): L(next_two_double_words):
and $15, %dh and $15, %dh
jz L(fourth_double_word) jz L(fourth_double_word)
mov 8(%edi), %eax mov 8(%esi), %ecx
sub 8(%esi), %eax cmp %ecx, 8(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(fourth_double_word): L(fourth_double_word):
mov 12(%edi), %eax mov 12(%esi), %ecx
sub 12(%esi), %eax cmp %ecx, 12(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(less4_double_words_16): L(less4_double_words_16):
xor %eax, %eax
test %dl, %dl test %dl, %dl
jz L(next_two_double_words_16) jz L(next_two_double_words_16)
and $15, %dl and $15, %dl
jz L(second_double_word_16) jz L(second_double_word_16)
mov 16(%edi), %eax mov 16(%esi), %ecx
sub 16(%esi), %eax cmp %ecx, 16(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(second_double_word_16): L(second_double_word_16):
mov 20(%edi), %eax mov 20(%esi), %ecx
sub 20(%esi), %eax cmp %ecx, 20(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(next_two_double_words_16): L(next_two_double_words_16):
and $15, %dh and $15, %dh
jz L(fourth_double_word_16) jz L(fourth_double_word_16)
mov 24(%edi), %eax mov 24(%esi), %ecx
sub 24(%esi), %eax cmp %ecx, 24(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(fourth_double_word_16): L(fourth_double_word_16):
mov 28(%edi), %eax mov 28(%esi), %ecx
sub 28(%esi), %eax cmp %ecx, 28(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(less4_double_words_32): L(less4_double_words_32):
xor %eax, %eax
test %dl, %dl test %dl, %dl
jz L(next_two_double_words_32) jz L(next_two_double_words_32)
and $15, %dl and $15, %dl
jz L(second_double_word_32) jz L(second_double_word_32)
mov 32(%edi), %eax mov 32(%esi), %ecx
sub 32(%esi), %eax cmp %ecx, 32(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(second_double_word_32): L(second_double_word_32):
mov 36(%edi), %eax mov 36(%esi), %ecx
sub 36(%esi), %eax cmp %ecx, 36(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(next_two_double_words_32): L(next_two_double_words_32):
and $15, %dh and $15, %dh
jz L(fourth_double_word_32) jz L(fourth_double_word_32)
mov 40(%edi), %eax mov 40(%esi), %ecx
sub 40(%esi), %eax cmp %ecx, 40(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(fourth_double_word_32): L(fourth_double_word_32):
mov 44(%edi), %eax mov 44(%esi), %ecx
sub 44(%esi), %eax cmp %ecx, 44(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(less4_double_words_48): L(less4_double_words_48):
xor %eax, %eax
test %dl, %dl test %dl, %dl
jz L(next_two_double_words_48) jz L(next_two_double_words_48)
and $15, %dl and $15, %dl
jz L(second_double_word_48) jz L(second_double_word_48)
mov 48(%edi), %eax mov 48(%esi), %ecx
sub 48(%esi), %eax cmp %ecx, 48(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(second_double_word_48): L(second_double_word_48):
mov 52(%edi), %eax mov 52(%esi), %ecx
sub 52(%esi), %eax cmp %ecx, 52(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(next_two_double_words_48): L(next_two_double_words_48):
and $15, %dh and $15, %dh
jz L(fourth_double_word_48) jz L(fourth_double_word_48)
mov 56(%edi), %eax mov 56(%esi), %ecx
sub 56(%esi), %eax cmp %ecx, 56(%edi)
jne L(nequal)
RETURN RETURN
.p2align 4 .p2align 4
L(fourth_double_word_48): L(fourth_double_word_48):
mov 60(%edi), %eax mov 60(%esi), %ecx
sub 60(%esi), %eax cmp %ecx, 60(%edi)
RETURN jne L(nequal)
.p2align 4
L(return):
RETURN RETURN
.p2align 4 .p2align 4
L(nequal): L(nequal):
mov $1, %eax mov $1, %eax
ja L(nequal_bigger) jg L(return)
neg %eax neg %eax
RETURN
L(nequal_bigger): .p2align 4
L(return):
RETURN RETURN
.p2align 4 .p2align 4
@ -988,7 +1004,7 @@ L(equal):
.p2align 4 .p2align 4
L(neq): L(neq):
mov $1, %eax mov $1, %eax
ja L(neq_bigger) jg L(neq_bigger)
neg %eax neg %eax
L(neq_bigger): L(neq_bigger):
@ -999,5 +1015,5 @@ L(eq):
xorl %eax, %eax xorl %eax, %eax
ret ret
END (STRCMP) END (__wcscmp_sse2)
#endif #endif

View File

@ -20,6 +20,8 @@
#include <sysdep.h> #include <sysdep.h>
/* Note: wcscmp uses signed comparison, not unsighed as in strcmp function. */
.text .text
ENTRY (wcscmp) ENTRY (wcscmp)
/* /*
@ -209,20 +211,20 @@ L(continue_00_48):
test %ecx, %ecx test %ecx, %ecx
jnz L(less4_double_words1) jnz L(less4_double_words1)
sub (%rsi), %eax cmp (%rsi), %eax
jnz L(return) jne L(nequal)
mov 4(%rdi), %eax mov 4(%rdi), %eax
sub 4(%rsi), %eax cmp 4(%rsi), %eax
jnz L(return) jne L(nequal)
mov 8(%rdi), %eax mov 8(%rdi), %eax
sub 8(%rsi), %eax cmp 8(%rsi), %eax
jnz L(return) jne L(nequal)
mov 12(%rdi), %eax mov 12(%rdi), %eax
sub 12(%rsi), %eax cmp 12(%rsi), %eax
jnz L(return) jne L(nequal)
movdqu 16(%rsi), %xmm2 movdqu 16(%rsi), %xmm2
pcmpeqd %xmm2, %xmm0 /* Any null double_word? */ pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
@ -530,20 +532,20 @@ L(continue_48_00):
test %ecx, %ecx test %ecx, %ecx
jnz L(less4_double_words1) jnz L(less4_double_words1)
sub (%rsi), %eax cmp (%rsi), %eax
jnz L(return) jne L(nequal)
mov 4(%rdi), %eax mov 4(%rdi), %eax
sub 4(%rsi), %eax cmp 4(%rsi), %eax
jnz L(return) jne L(nequal)
mov 8(%rdi), %eax mov 8(%rdi), %eax
sub 8(%rsi), %eax cmp 8(%rsi), %eax
jnz L(return) jne L(nequal)
mov 12(%rdi), %eax mov 12(%rdi), %eax
sub 12(%rsi), %eax cmp 12(%rsi), %eax
jnz L(return) jne L(nequal)
movdqu 16(%rdi), %xmm1 movdqu 16(%rdi), %xmm1
pcmpeqd %xmm1, %xmm0 /* Any null double_word? */ pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
@ -784,25 +786,29 @@ L(less4_double_words1):
test %ecx, %ecx test %ecx, %ecx
jz L(equal) jz L(equal)
mov 12(%rsi), %edx mov 12(%rsi), %ecx
mov 12(%rdi), %eax cmp %ecx, 12(%rdi)
sub %edx, %eax jne L(nequal)
xor %eax, %eax
ret ret
.p2align 4 .p2align 4
L(less4_double_words): L(less4_double_words):
xor %eax, %eax
test %dl, %dl test %dl, %dl
jz L(next_two_double_words) jz L(next_two_double_words)
and $15, %dl and $15, %dl
jz L(second_double_word) jz L(second_double_word)
mov (%rdi), %eax mov (%rdi), %eax
sub (%rsi), %eax cmp (%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(second_double_word): L(second_double_word):
mov 4(%rdi), %eax mov 4(%rdi), %eax
sub 4(%rsi), %eax cmp 4(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
@ -810,29 +816,34 @@ L(next_two_double_words):
and $15, %dh and $15, %dh
jz L(fourth_double_word) jz L(fourth_double_word)
mov 8(%rdi), %eax mov 8(%rdi), %eax
sub 8(%rsi), %eax cmp 8(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(fourth_double_word): L(fourth_double_word):
mov 12(%rdi), %eax mov 12(%rdi), %eax
sub 12(%rsi), %eax cmp 12(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(less4_double_words_16): L(less4_double_words_16):
xor %eax, %eax
test %dl, %dl test %dl, %dl
jz L(next_two_double_words_16) jz L(next_two_double_words_16)
and $15, %dl and $15, %dl
jz L(second_double_word_16) jz L(second_double_word_16)
mov 16(%rdi), %eax mov 16(%rdi), %eax
sub 16(%rsi), %eax cmp 16(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(second_double_word_16): L(second_double_word_16):
mov 20(%rdi), %eax mov 20(%rdi), %eax
sub 20(%rsi), %eax cmp 20(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
@ -840,29 +851,34 @@ L(next_two_double_words_16):
and $15, %dh and $15, %dh
jz L(fourth_double_word_16) jz L(fourth_double_word_16)
mov 24(%rdi), %eax mov 24(%rdi), %eax
sub 24(%rsi), %eax cmp 24(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(fourth_double_word_16): L(fourth_double_word_16):
mov 28(%rdi), %eax mov 28(%rdi), %eax
sub 28(%rsi), %eax cmp 28(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(less4_double_words_32): L(less4_double_words_32):
xor %eax, %eax
test %dl, %dl test %dl, %dl
jz L(next_two_double_words_32) jz L(next_two_double_words_32)
and $15, %dl and $15, %dl
jz L(second_double_word_32) jz L(second_double_word_32)
mov 32(%rdi), %eax mov 32(%rdi), %eax
sub 32(%rsi), %eax cmp 32(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(second_double_word_32): L(second_double_word_32):
mov 36(%rdi), %eax mov 36(%rdi), %eax
sub 36(%rsi), %eax cmp 36(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
@ -870,29 +886,34 @@ L(next_two_double_words_32):
and $15, %dh and $15, %dh
jz L(fourth_double_word_32) jz L(fourth_double_word_32)
mov 40(%rdi), %eax mov 40(%rdi), %eax
sub 40(%rsi), %eax cmp 40(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(fourth_double_word_32): L(fourth_double_word_32):
mov 44(%rdi), %eax mov 44(%rdi), %eax
sub 44(%rsi), %eax cmp 44(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(less4_double_words_48): L(less4_double_words_48):
xor %eax, %eax
test %dl, %dl test %dl, %dl
jz L(next_two_double_words_48) jz L(next_two_double_words_48)
and $15, %dl and $15, %dl
jz L(second_double_word_48) jz L(second_double_word_48)
mov 48(%rdi), %eax mov 48(%rdi), %eax
sub 48(%rsi), %eax cmp 48(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(second_double_word_48): L(second_double_word_48):
mov 52(%rdi), %eax mov 52(%rdi), %eax
sub 52(%rsi), %eax cmp 52(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
@ -900,23 +921,21 @@ L(next_two_double_words_48):
and $15, %dh and $15, %dh
jz L(fourth_double_word_48) jz L(fourth_double_word_48)
mov 56(%rdi), %eax mov 56(%rdi), %eax
sub 56(%rsi), %eax cmp 56(%rsi), %eax
jne L(nequal)
ret ret
.p2align 4 .p2align 4
L(fourth_double_word_48): L(fourth_double_word_48):
mov 60(%rdi), %eax mov 60(%rdi), %eax
sub 60(%rsi), %eax cmp 60(%rsi), %eax
ret jne L(nequal)
.p2align 4
L(return):
ret ret
.p2align 4 .p2align 4
L(nequal): L(nequal):
mov $1, %eax mov $1, %eax
ja L(nequal_bigger) jg L(nequal_bigger)
neg %eax neg %eax
L(nequal_bigger): L(nequal_bigger):

View File

@ -37,11 +37,11 @@ WCSCMP (s1, s2)
{ {
c1 = (wint_t) *s1++; c1 = (wint_t) *s1++;
c2 = (wint_t) *s2++; c2 = (wint_t) *s2++;
if (c1 == L'\0') if (c2 == L'\0')
return c1 - c2; return c1 - c2;
} }
while (c1 == c2); while (c1 == c2);
return c1 - c2; return c1 < c2 ? -1 : 1;
} }
libc_hidden_def (WCSCMP) libc_hidden_def (WCSCMP)