1 | /* Set a block of memory to some byte value. |
2 | For SPARC v7. |
3 | Copyright (C) 1996-2024 Free Software Foundation, Inc. |
4 | This file is part of the GNU C Library. |
5 | |
6 | The GNU C Library is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Lesser General Public |
8 | License as published by the Free Software Foundation; either |
9 | version 2.1 of the License, or (at your option) any later version. |
10 | |
11 | The GNU C Library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Lesser General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Lesser General Public |
17 | License along with the GNU C Library; if not, see |
18 | <https://www.gnu.org/licenses/>. */ |
19 | |
20 | #include <sysdep.h> |
21 | |
22 | /* Store 64 bytes at (BASE + OFFSET) using value SOURCE. */ |
23 | #define ZERO_BIG_BLOCK(base, offset, source) \ |
24 | std source, [base + offset + 0x00]; \ |
25 | std source, [base + offset + 0x08]; \ |
26 | std source, [base + offset + 0x10]; \ |
27 | std source, [base + offset + 0x18]; \ |
28 | std source, [base + offset + 0x20]; \ |
29 | std source, [base + offset + 0x28]; \ |
30 | std source, [base + offset + 0x30]; \ |
31 | std source, [base + offset + 0x38]; |
32 | |
33 | #define ZERO_LAST_BLOCKS(base, offset, source) \ |
34 | std source, [base - offset - 0x38]; \ |
35 | std source, [base - offset - 0x30]; \ |
36 | std source, [base - offset - 0x28]; \ |
37 | std source, [base - offset - 0x20]; \ |
38 | std source, [base - offset - 0x18]; \ |
39 | std source, [base - offset - 0x10]; \ |
40 | std source, [base - offset - 0x08]; \ |
41 | std source, [base - offset - 0x00]; |
42 | |
43 | .text |
44 | .align 4 |
45 | ENTRY(memset) |
46 | and %o1, 0xff, %g3 |
47 | sll %g3, 8, %g2 |
48 | or %g3, %g2, %g3 |
49 | sll %g3, 16, %g2 |
50 | or %g3, %g2, %g3 |
51 | orcc %o2, %g0, %o1 |
52 | 1: cmp %o1, 7 |
53 | bleu 7f |
54 | mov %o0, %g1 |
55 | |
56 | andcc %o0, 3, %o2 |
57 | bne 3f |
58 | 5: andcc %o0, 4, %g0 |
59 | |
60 | be 2f |
61 | mov %g3, %g2 |
62 | |
63 | st %g3, [%o0] |
64 | sub %o1, 4, %o1 |
65 | add %o0, 4, %o0 |
66 | 2: andcc %o1, 0xffffff80, %o3 |
67 | be 9f |
68 | andcc %o1, 0x78, %o2 |
69 | 4: ZERO_BIG_BLOCK (%o0, 0x00, %g2) |
70 | subcc %o3, 128, %o3 |
71 | ZERO_BIG_BLOCK (%o0, 0x40, %g2) |
72 | bne 4b |
73 | add %o0, 128, %o0 |
74 | |
75 | orcc %o2, %g0, %g0 |
76 | 9: be 6f |
77 | andcc %o1, 7, %o1 |
78 | |
79 | mov %o7, %g4 |
80 | 101: call 100f |
81 | srl %o2, 1, %o3 |
82 | mov %g4, %o7 |
83 | jmpl %o4 + (20f + 64 - 101b), %g0 |
84 | add %o0, %o2, %o0 |
85 | |
86 | 100: retl |
87 | sub %o7, %o3, %o4 |
88 | |
89 | 20: ZERO_LAST_BLOCKS(%o0, 0x48, %g2) |
90 | ZERO_LAST_BLOCKS(%o0, 0x08, %g2) |
91 | |
92 | 6: be 8f |
93 | andcc %o1, 4, %g0 |
94 | be 1f |
95 | andcc %o1, 2, %g0 |
96 | st %g3, [%o0] |
97 | add %o0, 4, %o0 |
98 | 1: be 1f |
99 | andcc %o1, 1, %g0 |
100 | sth %g3, [%o0] |
101 | add %o0, 2, %o0 |
102 | 1: bne,a 8f |
103 | stb %g3, [%o0] |
104 | 8: retl |
105 | mov %g1, %o0 |
106 | 7: orcc %o1, 0, %g0 |
107 | be 0f |
108 | subcc %o1, 1, %o1 |
109 | stb %g3, [%o0] |
110 | be 0f |
111 | subcc %o1, 1, %o1 |
112 | stb %g3, [%o0 + 1] |
113 | be 0f |
114 | subcc %o1, 1, %o1 |
115 | stb %g3, [%o0 + 2] |
116 | be 0f |
117 | subcc %o1, 1, %o1 |
118 | stb %g3, [%o0 + 3] |
119 | be 0f |
120 | subcc %o1, 1, %o1 |
121 | stb %g3, [%o0 + 4] |
122 | be 0f |
123 | subcc %o1, 1, %o1 |
124 | stb %g3, [%o0 + 5] |
125 | be 0f |
126 | subcc %o1, 1, %o1 |
127 | stb %g3, [%o0 + 6] |
128 | 0: retl |
129 | nop |
130 | |
131 | 3: cmp %o2, 3 |
132 | be 2f |
133 | stb %g3, [%o0] |
134 | |
135 | cmp %o2, 2 |
136 | be 2f |
137 | stb %g3, [%o0 + 0x01] |
138 | |
139 | stb %g3, [%o0 + 0x02] |
140 | 2: sub %o2, 4, %o2 |
141 | add %o1, %o2, %o1 |
142 | b 5b |
143 | sub %o0, %o2, %o0 |
144 | END(memset) |
145 | libc_hidden_builtin_def (memset) |
146 | |