mirror of
git://sourceware.org/git/glibc.git
synced 2024-12-03 04:01:43 +08:00
c5cc45148c
i586 strcpy.S used a clever trick with LEA to implement jump table: /* ECX has the last 2 bits of the address of source - 1. */ andl $3, %ecx call 2f 2: popl %edx /* 0xb is the distance between 2: and 1:. */ leal 0xb(%edx,%ecx,8), %ecx jmp *%ecx .align 8 1: /* ECX == 0 */ orb (%esi), %al jz L(end) stosb xorl %eax, %eax incl %esi /* ECX == 1 */ orb (%esi), %al jz L(end) stosb xorl %eax, %eax incl %esi /* ECX == 2 */ orb (%esi), %al jz L(end) stosb xorl %eax, %eax incl %esi /* ECX == 3 */ L(1): movl (%esi), %ecx leal 4(%esi),%esi This fails if there are instruction length changes before L(1):. This patch replaces it with conditional branches: cmpb $2, %cl je L(Src2) ja L(Src3) cmpb $1, %cl je L(Src1) L(Src0): which have similar performance and work with any instruction lengths. Tested on i586 and i686 with and without --disable-multi-arch. [BZ #22353] * sysdeps/i386/i586/strcpy.S (STRCPY): Use conditional branches. (1): Renamed to ... (L(Src0)): This. (L(Src1)): New. (L(Src2)): Likewise. (L(1)): Renamed to ... (L(Src3)): This. |
||
---|---|---|
.. | ||
add_n.S | ||
addmul_1.S | ||
bzero.S | ||
init-arch.h | ||
lshift.S | ||
memcopy.h | ||
memcpy.S | ||
mempcpy.S | ||
memset.S | ||
memusage.h | ||
mul_1.S | ||
rshift.S | ||
stpcpy.S | ||
strchr.S | ||
strcpy.S | ||
strlen.S | ||
sub_n.S | ||
submul_1.S |