1 | /* The assembly function for memset. 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 (memset) |
22 | /* Test if len less than 4 bytes. */ |
23 | mov r12, r0 |
24 | cmplti r2, 8 |
25 | bt .L_set_by_byte |
26 | |
27 | andi r13, r0, 3 |
28 | movi r19, 4 |
29 | /* Test if dest is not 4 bytes aligned. */ |
30 | bnez r13, .L_dest_not_aligned |
31 | /* Hardware can handle unaligned access directly. */ |
32 | .L_dest_aligned: |
33 | zextb r1, r1 |
34 | mov r3, r1 |
35 | lsli r1, 8 |
36 | or r1, r3 |
37 | lsli r3, r1, 16 |
38 | or r3, r1 |
39 | |
40 | /* If dest is aligned, then copy. */ |
41 | zext r18, r2, 31, 4 |
42 | /* Test if len less than 16 bytes. */ |
43 | bez r18, .L_len_less_16bytes |
44 | |
45 | LABLE_ALIGN |
46 | .L_len_larger_16bytes: |
47 | stw r3, (r0, 0) |
48 | stw r3, (r0, 4) |
49 | stw r3, (r0, 8) |
50 | stw r3, (r0, 12) |
51 | PRE_BNEZAD (r18) |
52 | addi r0, 16 |
53 | BNEZAD (r18, .L_len_larger_16bytes) |
54 | |
55 | .L_len_less_16bytes: |
56 | zext r18, r2, 3, 2 |
57 | andi r2, 3 |
58 | bez r18, .L_set_by_byte |
59 | .L_len_less_16bytes_loop: |
60 | stw r3, (r0, 0) |
61 | PRE_BNEZAD (r18) |
62 | addi r0, 4 |
63 | BNEZAD (r18, .L_len_less_16bytes_loop) |
64 | |
65 | /* Test if len less than 4 bytes. */ |
66 | .L_set_by_byte: |
67 | zext r18, r2, 2, 0 |
68 | bez r18, .L_return |
69 | .L_set_by_byte_loop: |
70 | stb r1, (r0, 0) |
71 | PRE_BNEZAD (r18) |
72 | addi r0, 1 |
73 | BNEZAD (r18, .L_set_by_byte_loop) |
74 | |
75 | .L_return: |
76 | mov r0, r12 |
77 | rts |
78 | |
79 | /* If dest is not aligned, just set some bytes makes the dest |
80 | align. */ |
81 | |
82 | .L_dest_not_aligned: |
83 | sub r13, r19, r13 |
84 | sub r2, r13 |
85 | .L_dest_not_aligned_loop: |
86 | /* Makes the dest align. */ |
87 | stb r1, (r0, 0) |
88 | PRE_BNEZAD (r13) |
89 | addi r0, 1 |
90 | BNEZAD (r13, .L_dest_not_aligned_loop) |
91 | cmplti r2, 8 |
92 | bt .L_set_by_byte |
93 | /* Check whether the src is aligned. */ |
94 | br .L_dest_aligned |
95 | END (memset) |
96 | |
97 | libc_hidden_builtin_def (memset) |
98 | .weak memset |
99 | |