diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/i386/i586/strchr.S | 16 | ||||
-rw-r--r-- | sysdeps/i386/i586/strlen.S | 26 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/init-first.h | 31 |
3 files changed, 50 insertions, 23 deletions
diff --git a/sysdeps/i386/i586/strchr.S b/sysdeps/i386/i586/strchr.S index 30de6b069d..100cbbc706 100644 --- a/sysdeps/i386/i586/strchr.S +++ b/sysdeps/i386/i586/strchr.S @@ -1,6 +1,6 @@ /* strchr -- find character CH in a NUL terminated string. Highly optimized version for ix85, x>=5. -Copyright (C) 1995 Free Software Foundation, Inc. +Copyright (C) 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>. @@ -68,9 +68,10 @@ ENTRY (strchr) andl $3, %edi /* mask alignment bits */ jz L11 /* alignment is 0 => start loop */ + jp L0 /* exactly two bits set */ movb (%eax), %cl /* load single byte */ - cmpb %cl, %dl /* is byte == C? */ + cmpb (%eax), %dl /* is byte == C? */ je L2 /* aligned => return pointer */ @@ -78,26 +79,21 @@ ENTRY (strchr) je L3 /* yes => return NULL */ incl %eax /* increment pointer */ - cmp $3, %edi /* was alignment == 3? */ + xorl $3, %edi /* was alignment == 3? */ +L0: movb (%eax), %cl /* load single byte */ je L11 /* yes => start loop */ - movb (%eax), %cl /* load single byte */ cmpb %cl, %dl /* is byte == C? */ - je L2 /* aligned => return pointer */ cmpb $0, %cl /* is byte NUL? */ je L3 /* yes => return NULL */ + movb 1(%eax), %cl /* load single byte */ incl %eax /* increment pointer */ - cmp $2, %edi /* was alignment == 2? */ - je L11 /* yes => start loop */ - - movb (%eax), %cl /* load single byte */ cmpb %cl, %dl /* is byte == C? */ - je L2 /* aligned => return pointer */ cmpb $0, %cl /* is byte NUL? */ diff --git a/sysdeps/i386/i586/strlen.S b/sysdeps/i386/i586/strlen.S index 15d01947d4..1e17131389 100644 --- a/sysdeps/i386/i586/strlen.S +++ b/sysdeps/i386/i586/strlen.S @@ -42,32 +42,31 @@ Boston, MA 02111-1307, USA. */ .text ENTRY(strlen) movl 4(%esp), %eax /* get string pointer */ + movl $3, %edx /* load mask (= 3) */ - movl %eax, %ecx /* duplicate it */ - andl $3, %ecx /* mask alignment bits */ + andl %eax, %edx /* separate last two bits of address */ - jz L11 /* aligned => start loop */ + jz L1 /* aligned => start loop */ + jp L0 /* exactly two bits set */ - cmpb %ch, (%eax) /* is byte NUL? */ + cmpb %dh, (%eax) /* is byte NUL? */ je L2 /* yes => return */ incl %eax /* increment pointer */ - cmpl $3, %ecx /* was alignment = 3? */ + xorl $3, %edx /* was alignment = 3? */ - je L11 /* yes => now it is aligned and start loop */ + jz L1 /* yes => now it is aligned and start loop */ - cmpb %ch, (%eax) /* is byte NUL? */ +L0: cmpb %dh, (%eax) /* is byte NUL? */ je L2 /* yes => return */ incl %eax /* increment pointer */ - cmpl $2, %ecx /* was alignment = 2? */ - je L11 /* yes => now it is aligned and start loop */ - - cmpb %ch, (%eax) /* is byte NUL? */ + cmpb %dh, (%eax) /* is byte NUL? */ je L2 /* yes => return */ incl %eax /* increment pointer */ + xorl %edx, %edx /* We need %edx == 0 for later */ /* We exit the loop if adding MAGIC_BITS to LONGWORD fails to change any of the hole bits of LONGWORD. @@ -88,8 +87,9 @@ ENTRY(strlen) into bit 16. Similarly, there will be a carry into bit 24. If one of bits 24-31 is set, there will be a carry into bit 32 (=carry flag), so all of the hole bits will - be changed. */ -L11: xorl %edx, %edx /* We need %edx == 0 for later */ + be changed. + + Note: %edx == 0 in any case here. */ L1: movl (%eax), %ecx /* get word (= 4 bytes) in question */ diff --git a/sysdeps/unix/sysv/linux/init-first.h b/sysdeps/unix/sysv/linux/init-first.h new file mode 100644 index 0000000000..dd4f85af9d --- /dev/null +++ b/sysdeps/unix/sysv/linux/init-first.h @@ -0,0 +1,31 @@ +/* The job of this fragment it to find argc and friends for INIT. + This is done in one of two ways: either in the stack context + of program start, or having dlopen pass them in. */ + +#define SYSDEP_CALL_INIT(NAME, INIT) \ +void NAME (void *arg) \ +{ \ + int argc; \ + char **argv, **envp; \ + /* The next variable is only here to work around a bug in gcc <= 2.7.2.1. \ + If the address would be taken inside the expression the optimizer \ + would try to be too smart and throws it away. Grrr. */ \ + int *dummy_addr = &_dl_starting_up; \ + \ + __libc_multiple_libcs = dummy_addr && !_dl_starting_up; \ + \ + if (!__libc_multiple_libcs) \ + { \ + argc = (int) arg; \ + argv = (char **) &arg + 1; \ + envp = &argv[argc+1]; \ + } \ + else \ + { \ + argc = (int) arg; \ + argv = ((char ***) &arg)[1]; \ + envp = ((char ***) &arg)[2]; \ + } \ + \ + INIT (argc, argv, envp); \ +} |