123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /* SPDX-License-Identifier: GPL-2.0 */
- // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
- #include <linux/linkage.h>
- #include "sysdep.h"
- ENTRY(memcmp)
- /* Test if len less than 4 bytes. */
- mov r3, r0
- movi r0, 0
- mov r12, r4
- cmplti r2, 4
- bt .L_compare_by_byte
- andi r13, r0, 3
- movi r19, 4
- /* Test if s1 is not 4 bytes aligned. */
- bnez r13, .L_s1_not_aligned
- LABLE_ALIGN
- .L_s1_aligned:
- /* If dest is aligned, then copy. */
- zext r18, r2, 31, 4
- /* Test if len less than 16 bytes. */
- bez r18, .L_compare_by_word
- .L_compare_by_4word:
- /* If aligned, load word each time. */
- ldw r20, (r3, 0)
- ldw r21, (r1, 0)
- /* If s1[i] != s2[i], goto .L_byte_check. */
- cmpne r20, r21
- bt .L_byte_check
- ldw r20, (r3, 4)
- ldw r21, (r1, 4)
- cmpne r20, r21
- bt .L_byte_check
- ldw r20, (r3, 8)
- ldw r21, (r1, 8)
- cmpne r20, r21
- bt .L_byte_check
- ldw r20, (r3, 12)
- ldw r21, (r1, 12)
- cmpne r20, r21
- bt .L_byte_check
- PRE_BNEZAD (r18)
- addi a3, 16
- addi a1, 16
- BNEZAD (r18, .L_compare_by_4word)
- .L_compare_by_word:
- zext r18, r2, 3, 2
- bez r18, .L_compare_by_byte
- .L_compare_by_word_loop:
- ldw r20, (r3, 0)
- ldw r21, (r1, 0)
- addi r3, 4
- PRE_BNEZAD (r18)
- cmpne r20, r21
- addi r1, 4
- bt .L_byte_check
- BNEZAD (r18, .L_compare_by_word_loop)
- .L_compare_by_byte:
- zext r18, r2, 1, 0
- bez r18, .L_return
- .L_compare_by_byte_loop:
- ldb r0, (r3, 0)
- ldb r4, (r1, 0)
- addi r3, 1
- subu r0, r4
- PRE_BNEZAD (r18)
- addi r1, 1
- bnez r0, .L_return
- BNEZAD (r18, .L_compare_by_byte_loop)
- .L_return:
- mov r4, r12
- rts
- # ifdef __CSKYBE__
- /* d[i] != s[i] in word, so we check byte 0. */
- .L_byte_check:
- xtrb0 r0, r20
- xtrb0 r2, r21
- subu r0, r2
- bnez r0, .L_return
- /* check byte 1 */
- xtrb1 r0, r20
- xtrb1 r2, r21
- subu r0, r2
- bnez r0, .L_return
- /* check byte 2 */
- xtrb2 r0, r20
- xtrb2 r2, r21
- subu r0, r2
- bnez r0, .L_return
- /* check byte 3 */
- xtrb3 r0, r20
- xtrb3 r2, r21
- subu r0, r2
- # else
- /* s1[i] != s2[i] in word, so we check byte 3. */
- .L_byte_check:
- xtrb3 r0, r20
- xtrb3 r2, r21
- subu r0, r2
- bnez r0, .L_return
- /* check byte 2 */
- xtrb2 r0, r20
- xtrb2 r2, r21
- subu r0, r2
- bnez r0, .L_return
- /* check byte 1 */
- xtrb1 r0, r20
- xtrb1 r2, r21
- subu r0, r2
- bnez r0, .L_return
- /* check byte 0 */
- xtrb0 r0, r20
- xtrb0 r2, r21
- subu r0, r2
- br .L_return
- # endif /* !__CSKYBE__ */
- /* Compare when s1 is not aligned. */
- .L_s1_not_aligned:
- sub r13, r19, r13
- sub r2, r13
- .L_s1_not_aligned_loop:
- ldb r0, (r3, 0)
- ldb r4, (r1, 0)
- addi r3, 1
- subu r0, r4
- PRE_BNEZAD (r13)
- addi r1, 1
- bnez r0, .L_return
- BNEZAD (r13, .L_s1_not_aligned_loop)
- br .L_s1_aligned
- ENDPROC(memcmp)
|