1/* The assembly function for memory 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
21ENTRY (memcmp)
22 /* Test if len less than 4 bytes. */
23 mov r3, r0
24 movi r0, 0
25 mov r12, r4
26 cmplti r2, 4
27 jbt .L_compare_by_byte
28
29 andi r13, r0, 3
30 movi r19, 4
31 /* Test if s1 is not 4 bytes aligned. */
32 bnez r13, .L_s1_not_aligned
33
34 LABLE_ALIGN
35.L_s1_aligned:
36 /* If dest is aligned, then copy. */
37 zext r18, r2, 31, 4
38 /* Test if len less than 16 bytes. */
39 bez r18, .L_compare_by_word
40
41.L_compare_by_4word:
42 /* If aligned, load word each time. */
43 ldw r20, (r3, 0)
44 ldw r21, (r1, 0)
45 /* If s1[i] != s2[i], goto .L_byte_check. */
46 cmpne r20, r21
47 bt .L_byte_check
48
49 ldw r20, (r3, 4)
50 ldw r21, (r1, 4)
51 cmpne r20, r21
52 bt .L_byte_check
53
54 ldw r20, (r3, 8)
55 ldw r21, (r1, 8)
56 cmpne r20, r21
57 bt .L_byte_check
58
59 ldw r20, (r3, 12)
60 ldw r21, (r1, 12)
61 cmpne r20, r21
62 bt .L_byte_check
63
64 PRE_BNEZAD (r18)
65 addi a3, 16
66 addi a1, 16
67
68 BNEZAD (r18, .L_compare_by_4word)
69
70.L_compare_by_word:
71 zext r18, r2, 3, 2
72 bez r18, .L_compare_by_byte
73.L_compare_by_word_loop:
74 ldw r20, (r3, 0)
75 ldw r21, (r1, 0)
76 addi r3, 4
77 PRE_BNEZAD (r18)
78 cmpne r20, r21
79 addi r1, 4
80 bt .L_byte_check
81 BNEZAD (r18, .L_compare_by_word_loop)
82
83.L_compare_by_byte:
84 zext r18, r2, 1, 0
85 bez r18, .L_return
86.L_compare_by_byte_loop:
87 ldb r0, (r3, 0)
88 ldb r4, (r1, 0)
89 addi r3, 1
90 subu r0, r4
91 PRE_BNEZAD (r18)
92 addi r1, 1
93 bnez r0, .L_return
94 BNEZAD (r18, .L_compare_by_byte_loop)
95
96.L_return:
97 mov r4, r12
98 rts
99
100 /* s1[i] != s2[i] in word, so we check byte 3. */
101.L_byte_check:
102 xtrb3 r0, r20
103 xtrb3 r2, r21
104 subu r0, r2
105 bnez r0, .L_return
106
107 /* check byte 2 */
108 xtrb2 r0, r20
109 xtrb2 r2, r21
110 subu r0, r2
111 bnez r0, .L_return
112
113 /* check byte 1 */
114 xtrb1 r0, r20
115 xtrb1 r2, r21
116 subu r0, r2
117 bnez r0, .L_return
118
119 /* check byte 0 */
120 xtrb0 r0, r20
121 xtrb0 r2, r21
122 subu r0, r2
123 br .L_return
124
125 /* Compare when s1 is not aligned. */
126.L_s1_not_aligned:
127 sub r13, r19, r13
128 sub r2, r13
129.L_s1_not_aligned_loop:
130 ldb r0, (r3, 0)
131 ldb r4, (r1, 0)
132 addi r3, 1
133 subu r0, r4
134 PRE_BNEZAD (r13)
135 addi r1, 1
136 bnez r0, .L_return
137 BNEZAD (r13, .L_s1_not_aligned_loop)
138 br .L_s1_aligned
139END (memcmp)
140weak_alias (memcmp, bcmp)
141strong_alias (memcmp, __memcmpeq)
142libc_hidden_def (memcmp)
143libc_hidden_def (__memcmpeq)
144.weak memcmp
145

source code of glibc/sysdeps/csky/abiv2/memcmp.S