1 /* SPDX-License-Identifier: GPL-2.0 */
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3 
4 #include <linux/linkage.h>
5 #include "sysdep.h"
6 
7 ENTRY(memcmp)
8 	/* Test if len less than 4 bytes.  */
9 	mov	r3, r0
10 	movi	r0, 0
11 	mov	r12, r4
12 	cmplti	r2, 4
13 	bt	.L_compare_by_byte
14 
15 	andi	r13, r0, 3
16 	movi	r19, 4
17 
18 	/* Test if s1 is not 4 bytes aligned.  */
19 	bnez	r13, .L_s1_not_aligned
20 
21 	LABLE_ALIGN
22 .L_s1_aligned:
23 	/* If dest is aligned, then copy.  */
24 	zext	r18, r2, 31, 4
25 	/* Test if len less than 16 bytes.  */
26 	bez	r18, .L_compare_by_word
27 
28 .L_compare_by_4word:
29 	/* If aligned, load word each time.  */
30 	ldw	r20, (r3, 0)
31 	ldw	r21, (r1, 0)
32 	/* If s1[i] != s2[i], goto .L_byte_check.  */
33 	cmpne	r20, r21
34 	bt	.L_byte_check
35 
36 	ldw	r20, (r3, 4)
37 	ldw	r21, (r1, 4)
38 	cmpne	r20, r21
39 	bt	.L_byte_check
40 
41 	ldw	r20, (r3, 8)
42 	ldw	r21, (r1, 8)
43 	cmpne	r20, r21
44 	bt	.L_byte_check
45 
46 	ldw	r20, (r3, 12)
47 	ldw	r21, (r1, 12)
48 	cmpne	r20, r21
49 	bt	.L_byte_check
50 
51 	PRE_BNEZAD (r18)
52 	addi	a3, 16
53 	addi	a1, 16
54 
55 	BNEZAD (r18, .L_compare_by_4word)
56 
57 .L_compare_by_word:
58 	zext	r18, r2, 3, 2
59 	bez	r18, .L_compare_by_byte
60 .L_compare_by_word_loop:
61 	ldw	r20, (r3, 0)
62 	ldw	r21, (r1, 0)
63 	addi	r3, 4
64 	PRE_BNEZAD (r18)
65 	cmpne	r20, r21
66 	addi    r1, 4
67 	bt	.L_byte_check
68 	BNEZAD (r18, .L_compare_by_word_loop)
69 
70 .L_compare_by_byte:
71         zext    r18, r2, 1, 0
72         bez     r18, .L_return
73 .L_compare_by_byte_loop:
74         ldb     r0, (r3, 0)
75         ldb     r4, (r1, 0)
76         addi    r3, 1
77         subu    r0, r4
78         PRE_BNEZAD (r18)
79         addi    r1, 1
80         bnez    r0, .L_return
81         BNEZAD (r18, .L_compare_by_byte_loop)
82 
83 .L_return:
84         mov     r4, r12
85         rts
86 
87 # ifdef __CSKYBE__
88 /* d[i] != s[i] in word, so we check byte 0.  */
89 .L_byte_check:
90         xtrb0   r0, r20
91         xtrb0   r2, r21
92         subu    r0, r2
93         bnez    r0, .L_return
94 
95         /* check byte 1 */
96         xtrb1   r0, r20
97         xtrb1   r2, r21
98         subu    r0, r2
99         bnez    r0, .L_return
100 
101         /* check byte 2 */
102         xtrb2   r0, r20
103         xtrb2   r2, r21
104         subu    r0, r2
105         bnez    r0, .L_return
106 
107         /* check byte 3 */
108         xtrb3   r0, r20
109         xtrb3   r2, r21
110         subu    r0, r2
111 # else
112 /* s1[i] != s2[i] in word, so we check byte 3.  */
113 .L_byte_check:
114 	xtrb3	r0, r20
115 	xtrb3	r2, r21
116         subu    r0, r2
117         bnez    r0, .L_return
118 
119 	/* check byte 2 */
120 	xtrb2	r0, r20
121 	xtrb2	r2, r21
122         subu    r0, r2
123         bnez    r0, .L_return
124 
125 	/* check byte 1 */
126 	xtrb1	r0, r20
127 	xtrb1	r2, r21
128 	subu	r0, r2
129 	bnez    r0, .L_return
130 
131 	/* check byte 0 */
132 	xtrb0	r0, r20
133 	xtrb0	r2, r21
134 	subu	r0, r2
135 	br	.L_return
136 # endif /* !__CSKYBE__ */
137 
138 /* Compare when s1 is not aligned.  */
139 .L_s1_not_aligned:
140 	sub	r13, r19, r13
141 	sub	r2, r13
142 .L_s1_not_aligned_loop:
143 	ldb	r0, (r3, 0)
144 	ldb	r4, (r1, 0)
145 	addi	r3, 1
146 	subu	r0, r4
147 	PRE_BNEZAD (r13)
148 	addi	r1, 1
149 	bnez	r0, .L_return
150 	BNEZAD (r13, .L_s1_not_aligned_loop)
151 	br	.L_s1_aligned
152 ENDPROC(memcmp)
153