xref: /kernel/linux/linux-5.10/arch/csky/abiv2/memcmp.S (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#include <linux/linkage.h>
58c2ecf20Sopenharmony_ci#include "sysdep.h"
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciENTRY(memcmp)
88c2ecf20Sopenharmony_ci	/* Test if len less than 4 bytes.  */
98c2ecf20Sopenharmony_ci	mov	r3, r0
108c2ecf20Sopenharmony_ci	movi	r0, 0
118c2ecf20Sopenharmony_ci	mov	r12, r4
128c2ecf20Sopenharmony_ci	cmplti	r2, 4
138c2ecf20Sopenharmony_ci	bt	.L_compare_by_byte
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci	andi	r13, r0, 3
168c2ecf20Sopenharmony_ci	movi	r19, 4
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci	/* Test if s1 is not 4 bytes aligned.  */
198c2ecf20Sopenharmony_ci	bnez	r13, .L_s1_not_aligned
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	LABLE_ALIGN
228c2ecf20Sopenharmony_ci.L_s1_aligned:
238c2ecf20Sopenharmony_ci	/* If dest is aligned, then copy.  */
248c2ecf20Sopenharmony_ci	zext	r18, r2, 31, 4
258c2ecf20Sopenharmony_ci	/* Test if len less than 16 bytes.  */
268c2ecf20Sopenharmony_ci	bez	r18, .L_compare_by_word
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci.L_compare_by_4word:
298c2ecf20Sopenharmony_ci	/* If aligned, load word each time.  */
308c2ecf20Sopenharmony_ci	ldw	r20, (r3, 0)
318c2ecf20Sopenharmony_ci	ldw	r21, (r1, 0)
328c2ecf20Sopenharmony_ci	/* If s1[i] != s2[i], goto .L_byte_check.  */
338c2ecf20Sopenharmony_ci	cmpne	r20, r21
348c2ecf20Sopenharmony_ci	bt	.L_byte_check
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	ldw	r20, (r3, 4)
378c2ecf20Sopenharmony_ci	ldw	r21, (r1, 4)
388c2ecf20Sopenharmony_ci	cmpne	r20, r21
398c2ecf20Sopenharmony_ci	bt	.L_byte_check
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	ldw	r20, (r3, 8)
428c2ecf20Sopenharmony_ci	ldw	r21, (r1, 8)
438c2ecf20Sopenharmony_ci	cmpne	r20, r21
448c2ecf20Sopenharmony_ci	bt	.L_byte_check
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	ldw	r20, (r3, 12)
478c2ecf20Sopenharmony_ci	ldw	r21, (r1, 12)
488c2ecf20Sopenharmony_ci	cmpne	r20, r21
498c2ecf20Sopenharmony_ci	bt	.L_byte_check
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	PRE_BNEZAD (r18)
528c2ecf20Sopenharmony_ci	addi	a3, 16
538c2ecf20Sopenharmony_ci	addi	a1, 16
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	BNEZAD (r18, .L_compare_by_4word)
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci.L_compare_by_word:
588c2ecf20Sopenharmony_ci	zext	r18, r2, 3, 2
598c2ecf20Sopenharmony_ci	bez	r18, .L_compare_by_byte
608c2ecf20Sopenharmony_ci.L_compare_by_word_loop:
618c2ecf20Sopenharmony_ci	ldw	r20, (r3, 0)
628c2ecf20Sopenharmony_ci	ldw	r21, (r1, 0)
638c2ecf20Sopenharmony_ci	addi	r3, 4
648c2ecf20Sopenharmony_ci	PRE_BNEZAD (r18)
658c2ecf20Sopenharmony_ci	cmpne	r20, r21
668c2ecf20Sopenharmony_ci	addi    r1, 4
678c2ecf20Sopenharmony_ci	bt	.L_byte_check
688c2ecf20Sopenharmony_ci	BNEZAD (r18, .L_compare_by_word_loop)
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci.L_compare_by_byte:
718c2ecf20Sopenharmony_ci        zext    r18, r2, 1, 0
728c2ecf20Sopenharmony_ci        bez     r18, .L_return
738c2ecf20Sopenharmony_ci.L_compare_by_byte_loop:
748c2ecf20Sopenharmony_ci        ldb     r0, (r3, 0)
758c2ecf20Sopenharmony_ci        ldb     r4, (r1, 0)
768c2ecf20Sopenharmony_ci        addi    r3, 1
778c2ecf20Sopenharmony_ci        subu    r0, r4
788c2ecf20Sopenharmony_ci        PRE_BNEZAD (r18)
798c2ecf20Sopenharmony_ci        addi    r1, 1
808c2ecf20Sopenharmony_ci        bnez    r0, .L_return
818c2ecf20Sopenharmony_ci        BNEZAD (r18, .L_compare_by_byte_loop)
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci.L_return:
848c2ecf20Sopenharmony_ci        mov     r4, r12
858c2ecf20Sopenharmony_ci        rts
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci# ifdef __CSKYBE__
888c2ecf20Sopenharmony_ci/* d[i] != s[i] in word, so we check byte 0.  */
898c2ecf20Sopenharmony_ci.L_byte_check:
908c2ecf20Sopenharmony_ci        xtrb0   r0, r20
918c2ecf20Sopenharmony_ci        xtrb0   r2, r21
928c2ecf20Sopenharmony_ci        subu    r0, r2
938c2ecf20Sopenharmony_ci        bnez    r0, .L_return
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci        /* check byte 1 */
968c2ecf20Sopenharmony_ci        xtrb1   r0, r20
978c2ecf20Sopenharmony_ci        xtrb1   r2, r21
988c2ecf20Sopenharmony_ci        subu    r0, r2
998c2ecf20Sopenharmony_ci        bnez    r0, .L_return
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci        /* check byte 2 */
1028c2ecf20Sopenharmony_ci        xtrb2   r0, r20
1038c2ecf20Sopenharmony_ci        xtrb2   r2, r21
1048c2ecf20Sopenharmony_ci        subu    r0, r2
1058c2ecf20Sopenharmony_ci        bnez    r0, .L_return
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci        /* check byte 3 */
1088c2ecf20Sopenharmony_ci        xtrb3   r0, r20
1098c2ecf20Sopenharmony_ci        xtrb3   r2, r21
1108c2ecf20Sopenharmony_ci        subu    r0, r2
1118c2ecf20Sopenharmony_ci# else
1128c2ecf20Sopenharmony_ci/* s1[i] != s2[i] in word, so we check byte 3.  */
1138c2ecf20Sopenharmony_ci.L_byte_check:
1148c2ecf20Sopenharmony_ci	xtrb3	r0, r20
1158c2ecf20Sopenharmony_ci	xtrb3	r2, r21
1168c2ecf20Sopenharmony_ci        subu    r0, r2
1178c2ecf20Sopenharmony_ci        bnez    r0, .L_return
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	/* check byte 2 */
1208c2ecf20Sopenharmony_ci	xtrb2	r0, r20
1218c2ecf20Sopenharmony_ci	xtrb2	r2, r21
1228c2ecf20Sopenharmony_ci        subu    r0, r2
1238c2ecf20Sopenharmony_ci        bnez    r0, .L_return
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	/* check byte 1 */
1268c2ecf20Sopenharmony_ci	xtrb1	r0, r20
1278c2ecf20Sopenharmony_ci	xtrb1	r2, r21
1288c2ecf20Sopenharmony_ci	subu	r0, r2
1298c2ecf20Sopenharmony_ci	bnez    r0, .L_return
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	/* check byte 0 */
1328c2ecf20Sopenharmony_ci	xtrb0	r0, r20
1338c2ecf20Sopenharmony_ci	xtrb0	r2, r21
1348c2ecf20Sopenharmony_ci	subu	r0, r2
1358c2ecf20Sopenharmony_ci	br	.L_return
1368c2ecf20Sopenharmony_ci# endif /* !__CSKYBE__ */
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci/* Compare when s1 is not aligned.  */
1398c2ecf20Sopenharmony_ci.L_s1_not_aligned:
1408c2ecf20Sopenharmony_ci	sub	r13, r19, r13
1418c2ecf20Sopenharmony_ci	sub	r2, r13
1428c2ecf20Sopenharmony_ci.L_s1_not_aligned_loop:
1438c2ecf20Sopenharmony_ci	ldb	r0, (r3, 0)
1448c2ecf20Sopenharmony_ci	ldb	r4, (r1, 0)
1458c2ecf20Sopenharmony_ci	addi	r3, 1
1468c2ecf20Sopenharmony_ci	subu	r0, r4
1478c2ecf20Sopenharmony_ci	PRE_BNEZAD (r13)
1488c2ecf20Sopenharmony_ci	addi	r1, 1
1498c2ecf20Sopenharmony_ci	bnez	r0, .L_return
1508c2ecf20Sopenharmony_ci	BNEZAD (r13, .L_s1_not_aligned_loop)
1518c2ecf20Sopenharmony_ci	br	.L_s1_aligned
1528c2ecf20Sopenharmony_ciENDPROC(memcmp)
153