* libc/machine/arm/strcmp.S: Use local labels.

This commit is contained in:
Corinna Vinschen 2013-06-05 09:41:21 +00:00
parent aa6aee7dd7
commit 925e1c8157
2 changed files with 52 additions and 48 deletions

View File

@ -1,3 +1,7 @@
2013-06-05 Joey Ye <joey.ye@arm.com>
* libc/machine/arm/strcmp.S: Use local labels.
2013-06-03 Joey Ye <joey.ye@arm.com> 2013-06-03 Joey Ye <joey.ye@arm.com>
* libc/machine/arm/Makefile.am (MEMCPY_DEP): New define. * libc/machine/arm/Makefile.am (MEMCPY_DEP): New define.

View File

@ -208,12 +208,12 @@ strcmp:
/* Are both strings double-word aligned? */ /* Are both strings double-word aligned? */
orr ip, r0, r1 orr ip, r0, r1
tst ip, #7 tst ip, #7
bne do_align bne .Ldo_align
/* Fast path. */ /* Fast path. */
init init
doubleword_aligned: .Ldoubleword_aligned:
/* Get here when the strings to compare are double-word aligned. */ /* Get here when the strings to compare are double-word aligned. */
/* Compare two words in every iteration. */ /* Compare two words in every iteration. */
@ -228,14 +228,14 @@ doubleword_aligned:
ldrd r2, r3, [r0], #8 ldrd r2, r3, [r0], #8
ldrd r4, r5, [r1], #8 ldrd r4, r5, [r1], #8
magic_compare_and_branch w1=r2, w2=r4, label=return_24 magic_compare_and_branch w1=r2, w2=r4, label=.Lreturn_24
magic_compare_and_branch w1=r3, w2=r5, label=return_35 magic_compare_and_branch w1=r3, w2=r5, label=.Lreturn_35
b 2b b 2b
do_align: .Ldo_align:
/* Is the first string word-aligned? */ /* Is the first string word-aligned? */
ands ip, r0, #3 ands ip, r0, #3
beq word_aligned_r0 beq .Lword_aligned_r0
/* Fast compare byte by byte until the first string is word-aligned. */ /* Fast compare byte by byte until the first string is word-aligned. */
/* The offset of r0 from a word boundary is in ip. Thus, the number of bytes /* The offset of r0 from a word boundary is in ip. Thus, the number of bytes
@ -243,58 +243,58 @@ do_align:
bic r0, r0, #3 bic r0, r0, #3
ldr r2, [r0], #4 ldr r2, [r0], #4
lsls ip, ip, #31 lsls ip, ip, #31
beq byte2 beq .Lbyte2
bcs byte3 bcs .Lbyte3
byte1: .Lbyte1:
ldrb ip, [r1], #1 ldrb ip, [r1], #1
uxtb r3, r2, ror #BYTE1_OFFSET uxtb r3, r2, ror #BYTE1_OFFSET
subs ip, r3, ip subs ip, r3, ip
bne fast_return bne .Lfast_return
m_cbz reg=r3, label=fast_return m_cbz reg=r3, label=.Lfast_return
byte2: .Lbyte2:
ldrb ip, [r1], #1 ldrb ip, [r1], #1
uxtb r3, r2, ror #BYTE2_OFFSET uxtb r3, r2, ror #BYTE2_OFFSET
subs ip, r3, ip subs ip, r3, ip
bne fast_return bne .Lfast_return
m_cbz reg=r3, label=fast_return m_cbz reg=r3, label=.Lfast_return
byte3: .Lbyte3:
ldrb ip, [r1], #1 ldrb ip, [r1], #1
uxtb r3, r2, ror #BYTE3_OFFSET uxtb r3, r2, ror #BYTE3_OFFSET
subs ip, r3, ip subs ip, r3, ip
bne fast_return bne .Lfast_return
m_cbnz reg=r3, label=word_aligned_r0 m_cbnz reg=r3, label=.Lword_aligned_r0
fast_return: .Lfast_return:
mov r0, ip mov r0, ip
bx lr bx lr
word_aligned_r0: .Lword_aligned_r0:
init init
/* The first string is word-aligned. */ /* The first string is word-aligned. */
/* Is the second string word-aligned? */ /* Is the second string word-aligned? */
ands ip, r1, #3 ands ip, r1, #3
bne strcmp_unaligned bne .Lstrcmp_unaligned
word_aligned: .Lword_aligned:
/* The strings are word-aligned. */ /* The strings are word-aligned. */
/* Is the first string double-word aligned? */ /* Is the first string double-word aligned? */
tst r0, #4 tst r0, #4
beq doubleword_aligned_r0 beq .Ldoubleword_aligned_r0
/* If r0 is not double-word aligned yet, align it by loading /* If r0 is not double-word aligned yet, align it by loading
and comparing the next word from each string. */ and comparing the next word from each string. */
ldr r2, [r0], #4 ldr r2, [r0], #4
ldr r4, [r1], #4 ldr r4, [r1], #4
magic_compare_and_branch w1=r2 w2=r4 label=return_24 magic_compare_and_branch w1=r2 w2=r4 label=.Lreturn_24
doubleword_aligned_r0: .Ldoubleword_aligned_r0:
/* Get here when r0 is double-word aligned. */ /* Get here when r0 is double-word aligned. */
/* Is r1 doubleword_aligned? */ /* Is r1 doubleword_aligned? */
tst r1, #4 tst r1, #4
beq doubleword_aligned beq .Ldoubleword_aligned
/* Get here when the strings to compare are word-aligned, /* Get here when the strings to compare are word-aligned,
r0 is double-word aligned, but r1 is not double-word aligned. */ r0 is double-word aligned, but r1 is not double-word aligned. */
@ -312,9 +312,9 @@ doubleword_aligned_r0:
/* Load the next double-word from each string and compare. */ /* Load the next double-word from each string and compare. */
ldrd r2, r3, [r0], #8 ldrd r2, r3, [r0], #8
magic_compare_and_branch w1=r2 w2=r5 label=return_25 magic_compare_and_branch w1=r2 w2=r5 label=.Lreturn_25
ldrd r4, r5, [r1], #8 ldrd r4, r5, [r1], #8
magic_compare_and_branch w1=r3 w2=r4 label=return_34 magic_compare_and_branch w1=r3 w2=r4 label=.Lreturn_34
b 3b b 3b
.macro miscmp_word offsetlo offsethi .macro miscmp_word offsetlo offsethi
@ -338,47 +338,47 @@ doubleword_aligned_r0:
and r2, r3, r6, S2LOMEM #\offsetlo and r2, r3, r6, S2LOMEM #\offsetlo
it eq it eq
cmpeq r2, r5 cmpeq r2, r5
bne return_25 bne .Lreturn_25
ldr r5, [r1], #4 ldr r5, [r1], #4
cmp ip, #0 cmp ip, #0
eor r3, r2, r3 eor r3, r2, r3
S2HIMEM r2, r5, #\offsethi S2HIMEM r2, r5, #\offsethi
it eq it eq
cmpeq r3, r2 cmpeq r3, r2
bne return_32 bne .Lreturn_32
b 7b b 7b
.endm /* miscmp_word */ .endm /* miscmp_word */
strcmp_unaligned: .Lstrcmp_unaligned:
/* r0 is word-aligned, r1 is at offset ip from a word. */ /* r0 is word-aligned, r1 is at offset ip from a word. */
/* Align r1 to the (previous) word-boundary. */ /* Align r1 to the (previous) word-boundary. */
bic r1, r1, #3 bic r1, r1, #3
/* Unaligned comparison word by word using LDRs. */ /* Unaligned comparison word by word using LDRs. */
cmp ip, #2 cmp ip, #2
beq miscmp_word_16 /* If ip == 2. */ beq .Lmiscmp_word_16 /* If ip == 2. */
bge miscmp_word_24 /* If ip == 3. */ bge .Lmiscmp_word_24 /* If ip == 3. */
miscmp_word offsetlo=8 offsethi=24 /* If ip == 1. */ miscmp_word offsetlo=8 offsethi=24 /* If ip == 1. */
miscmp_word_16: miscmp_word offsetlo=16 offsethi=16 .Lmiscmp_word_16: miscmp_word offsetlo=16 offsethi=16
miscmp_word_24: miscmp_word offsetlo=24 offsethi=8 .Lmiscmp_word_24: miscmp_word offsetlo=24 offsethi=8
return_32: .Lreturn_32:
setup_return w1=r3, w2=r2 setup_return w1=r3, w2=r2
b do_return b .Ldo_return
return_34: .Lreturn_34:
setup_return w1=r3, w2=r4 setup_return w1=r3, w2=r4
b do_return b .Ldo_return
return_25: .Lreturn_25:
setup_return w1=r2, w2=r5 setup_return w1=r2, w2=r5
b do_return b .Ldo_return
return_35: .Lreturn_35:
setup_return w1=r3, w2=r5 setup_return w1=r3, w2=r5
b do_return b .Ldo_return
return_24: .Lreturn_24:
setup_return w1=r2, w2=r4 setup_return w1=r2, w2=r4
do_return: .Ldo_return:
#ifdef __ARMEB__ #ifdef __ARMEB__
mov r0, ip mov r0, ip
@ -394,7 +394,7 @@ do_return:
/* There is a zero or a different byte between r1 and r2. */ /* There is a zero or a different byte between r1 and r2. */
/* r0 contains a mask of all-zero bytes in r1. */ /* r0 contains a mask of all-zero bytes in r1. */
/* Using r0 and not ip here because cbz requires low register. */ /* Using r0 and not ip here because cbz requires low register. */
m_cbz reg=r0, label=compute_return_value m_cbz reg=r0, label=.Lcompute_return_value
clz r0, r0 clz r0, r0
/* r0 contains the number of bits on the left of the first all-zero byte in r1. */ /* r0 contains the number of bits on the left of the first all-zero byte in r1. */
rsb r0, r0, #24 rsb r0, r0, #24
@ -402,7 +402,7 @@ do_return:
lsr r1, r1, r0 lsr r1, r1, r0
lsr r2, r2, r0 lsr r2, r2, r0
compute_return_value: .Lcompute_return_value:
movs r0, #1 movs r0, #1
cmp r1, r2 cmp r1, r2
/* The return value is computed as follows. /* The return value is computed as follows.
@ -436,7 +436,7 @@ compute_return_value:
eor r2, r0, r1 eor r2, r0, r1
tst r2, #3 tst r2, #3
/* Strings not at same byte offset from a word boundary. */ /* Strings not at same byte offset from a word boundary. */
bne strcmp_unaligned bne .Lstrcmp_unaligned
ands r2, r0, #3 ands r2, r0, #3
bic r0, r0, #3 bic r0, r0, #3
bic r1, r1, #3 bic r1, r1, #3
@ -513,7 +513,7 @@ compute_return_value:
RETURN RETURN
strcmp_unaligned: .Lstrcmp_unaligned:
#if 0 #if 0
/* The assembly code below is based on the following alogrithm. */ /* The assembly code below is based on the following alogrithm. */