summaryrefslogtreecommitdiffstats
path: root/arch/csky/abiv2/strcmp.S
blob: f8403f4d8c2beb75b91da2e97c7d5161182ef7b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* SPDX-License-Identifier: GPL-2.0 */
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.

#include <linux/linkage.h>
#include "sysdep.h"

ENTRY(strcmp)
	mov	a3, a0
	/* Check if the s1 addr is aligned.  */
	xor	a2, a3, a1
	andi	a2, 0x3
	bnez	a2, 7f
	andi	t1, a0, 0x3
	bnez	t1, 5f

1:
	/* If aligned, load word each time.  */
	ldw	t0, (a3, 0)
	ldw	t1, (a1, 0)
	/* If s1[i] != s2[i], goto 2f.  */
	cmpne   t0, t1
	bt      2f
	/* If s1[i] == s2[i], check if s1 or s2 is at the end.  */
	tstnbz	t0
	/* If at the end, goto 3f (finish comparing).  */
	bf	3f

	ldw	t0, (a3, 4)
	ldw	t1, (a1, 4)
	cmpne	t0, t1
	bt	2f
	tstnbz	t0
	bf	3f

	ldw	t0, (a3, 8)
	ldw	t1, (a1, 8)
	cmpne	t0, t1
	bt	2f
	tstnbz	t0
	bf	3f

	ldw	t0, (a3, 12)
	ldw	t1, (a1, 12)
	cmpne	t0, t1
	bt	2f
	tstnbz	t0
	bf	3f

	ldw	t0, (a3, 16)
	ldw	t1, (a1, 16)
	cmpne	t0, t1
	bt	2f
	tstnbz	t0
	bf	3f

	ldw	t0, (a3, 20)
	ldw	t1, (a1, 20)
	cmpne	t0, t1
	bt	2f
	tstnbz	t0
	bf	3f

	ldw	t0, (a3, 24)
	ldw	t1, (a1, 24)
	cmpne	t0, t1
	bt	2f
	tstnbz	t0
	bf	3f

	ldw	t0, (a3, 28)
	ldw	t1, (a1, 28)
	cmpne	t0, t1
	bt	2f
	tstnbz	t0
	bf	3f

	addi	a3, 32
	addi	a1, 32

	br	1b

# ifdef __CSKYBE__
	/* d[i] != s[i] in word, so we check byte 0.  */
2:
	xtrb0   a0, t0
	xtrb0   a2, t1
	subu    a0, a2
	bez     a2, 4f
	bnez    a0, 4f

	/* check byte 1 */
	xtrb1   a0, t0
	xtrb1   a2, t1
	subu    a0, a2
	bez     a2, 4f
	bnez    a0, 4f

	/* check byte 2 */
	xtrb2   a0, t0
	xtrb2   a2, t1
	subu    a0, a2
	bez     a2, 4f
	bnez    a0, 4f

	/* check byte 3 */
	xtrb3   a0, t0
	xtrb3   a2, t1
	subu    a0, a2
# else
	/* s1[i] != s2[i] in word, so we check byte 3.  */
2:
	xtrb3	a0, t0
	xtrb3	a2, t1
	subu    a0, a2
	bez     a2, 4f
	bnez    a0, 4f

	/* check byte 2 */
	xtrb2	a0, t0
	xtrb2	a2, t1
	subu    a0, a2
	bez     a2, 4f
	bnez    a0, 4f

	/* check byte 1 */
	xtrb1	a0, t0
	xtrb1	a2, t1
	subu	a0, a2
	bez	a2, 4f
	bnez    a0, 4f

	/* check byte 0 */
	xtrb0	a0, t0
	xtrb0	a2, t1
	subu	a0, a2

# endif /* !__CSKYBE__ */
	jmp     lr
3:
	movi	a0, 0
4:
	jmp     lr

	/* Compare when s1 or s2 is not aligned.  */
5:
	subi    t1, 4
6:
	ldb	a0, (a3, 0)
	ldb	a2, (a1, 0)
	subu	a0, a2
	bez	a2, 4b
	bnez	a0, 4b
	addi    t1, 1
	addi	a1, 1
	addi	a3, 1
	bnez	t1, 6b
	br	1b

7:
	ldb	a0, (a3, 0)
	addi	a3, 1
	ldb	a2, (a1, 0)
	addi	a1, 1
	subu    a0, a2
	bnez    a0, 4b
	bnez	a2, 7b
	jmp	r15
ENDPROC(strcmp)