* libc/machine/arm/strcmp.S: Use local labels.
This commit is contained in:
parent
aa6aee7dd7
commit
925e1c8157
|
@ -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.
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
Loading…
Reference in New Issue