1 | /* The assembly function for string compare. C-SKY ABIV2 version. |
2 | Copyright (C) 2018-2024 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library. If not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #include <sysdep.h> |
20 | |
21 | ENTRY (strcmp) |
22 | mov a3, a0 |
23 | /* Check if the s1 addr is aligned. */ |
24 | xor a2, a3, a1 |
25 | andi a2, 0x3 |
26 | bnez a2, 7f |
27 | andi t1, a0, 0x3 |
28 | bnez t1, 5f |
29 | |
30 | 1: |
31 | /* If aligned, load word each time. */ |
32 | ldw t0, (a3, 0) |
33 | ldw t1, (a1, 0) |
34 | /* If s1[i] != s2[i], goto 2f. */ |
35 | cmpne t0, t1 |
36 | bt 2f |
37 | /* If s1[i] == s2[i], check if s1 or s2 is at the end. */ |
38 | tstnbz t0 |
39 | /* If at the end, goto 3f (finish comparing). */ |
40 | bf 3f |
41 | |
42 | ldw t0, (a3, 4) |
43 | ldw t1, (a1, 4) |
44 | cmpne t0, t1 |
45 | bt 2f |
46 | tstnbz t0 |
47 | bf 3f |
48 | |
49 | ldw t0, (a3, 8) |
50 | ldw t1, (a1, 8) |
51 | cmpne t0, t1 |
52 | bt 2f |
53 | tstnbz t0 |
54 | bf 3f |
55 | |
56 | ldw t0, (a3, 12) |
57 | ldw t1, (a1, 12) |
58 | cmpne t0, t1 |
59 | bt 2f |
60 | tstnbz t0 |
61 | bf 3f |
62 | |
63 | ldw t0, (a3, 16) |
64 | ldw t1, (a1, 16) |
65 | cmpne t0, t1 |
66 | bt 2f |
67 | tstnbz t0 |
68 | bf 3f |
69 | |
70 | ldw t0, (a3, 20) |
71 | ldw t1, (a1, 20) |
72 | cmpne t0, t1 |
73 | bt 2f |
74 | tstnbz t0 |
75 | bf 3f |
76 | |
77 | ldw t0, (a3, 24) |
78 | ldw t1, (a1, 24) |
79 | cmpne t0, t1 |
80 | bt 2f |
81 | tstnbz t0 |
82 | bf 3f |
83 | |
84 | ldw t0, (a3, 28) |
85 | ldw t1, (a1, 28) |
86 | cmpne t0, t1 |
87 | bt 2f |
88 | tstnbz t0 |
89 | bf 3f |
90 | |
91 | addi a3, 32 |
92 | addi a1, 32 |
93 | |
94 | br 1b |
95 | |
96 | /* s1[i] != s2[i] in word, so we check byte 3. */ |
97 | 2: |
98 | xtrb3 a0, t0 |
99 | xtrb3 a2, t1 |
100 | subu a0, a2 |
101 | bez a2, 4f |
102 | bnez a0, 4f |
103 | |
104 | /* Check byte 2. */ |
105 | xtrb2 a0, t0 |
106 | xtrb2 a2, t1 |
107 | subu a0, a2 |
108 | bez a2, 4f |
109 | bnez a0, 4f |
110 | |
111 | /* Check byte 1. */ |
112 | xtrb1 a0, t0 |
113 | xtrb1 a2, t1 |
114 | subu a0, a2 |
115 | bez a2, 4f |
116 | bnez a0, 4f |
117 | |
118 | /* Check byte 0. */ |
119 | xtrb0 a0, t0 |
120 | xtrb0 a2, t1 |
121 | subu a0, a2 |
122 | |
123 | jmp lr |
124 | 3: |
125 | movi a0, 0 |
126 | 4: |
127 | jmp lr |
128 | |
129 | /* Compare when s1 or s2 is not aligned. */ |
130 | 5: |
131 | subi t1, 4 |
132 | 6: |
133 | ldb a0, (a3, 0) |
134 | ldb a2, (a1, 0) |
135 | subu a0, a2 |
136 | bnez a0, 4b |
137 | addi t1, 1 |
138 | bez a2, 4b |
139 | addi a1, 1 |
140 | addi a3, 1 |
141 | bez t1, 1b |
142 | br 6b |
143 | |
144 | 7: |
145 | ldb a0, (a3, 0) |
146 | addi a3, 1 |
147 | ldb a2, (a1, 0) |
148 | addi a1, 1 |
149 | subu a0, a2 |
150 | bnez a0, 4b |
151 | bnez a2, 7b |
152 | jmp r15 |
153 | END (strcmp) |
154 | |
155 | libc_hidden_def (strcmp) |
156 | .weak strcmp |
157 | |