]>
Commit | Line | Data |
---|---|---|
c0a99f02 | 1 | /* |
d85bb55f | 2 | Copyright (c) 2015-2024, Synopsys, Inc. All rights reserved. |
c0a99f02 AK |
3 | |
4 | Redistribution and use in source and binary forms, with or without | |
5 | modification, are permitted provided that the following conditions are met: | |
6 | ||
7 | 1) Redistributions of source code must retain the above copyright notice, | |
8 | this list of conditions and the following disclaimer. | |
9 | ||
10 | 2) Redistributions in binary form must reproduce the above copyright notice, | |
11 | this list of conditions and the following disclaimer in the documentation | |
12 | and/or other materials provided with the distribution. | |
13 | ||
14 | 3) Neither the name of the Synopsys, Inc., nor the names of its contributors | |
15 | may be used to endorse or promote products derived from this software | |
16 | without specific prior written permission. | |
17 | ||
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
21 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
22 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
23 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
24 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
25 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
26 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
28 | POSSIBILITY OF SUCH DAMAGE. | |
29 | */ | |
30 | ||
31 | /* This implementation is optimized for performance. For code size a generic | |
32 | implementation of this function from newlib/libc/string/memset.c will be | |
33 | used. */ | |
d85bb55f CZ |
34 | #if !defined (__OPTIMIZE_SIZE__) && !defined (PREFER_SIZE_OVER_SPEED) \ |
35 | && !defined (__ARC_RF16__) | |
c0a99f02 AK |
36 | |
37 | #include "asm.h" | |
38 | ||
39 | /* ARC HS has it's own implementation of memset, yet we want this function | |
40 | still to be compiled under "__dummy_memset" disguise, because strncpy | |
41 | function uses __strncpy_bzero as a second entry point into memset. Would be | |
42 | better to add __strncpy_bzero label to memset for ARC HS though, and even | |
43 | better would be to avoid a second entry point into function. ARC HS always | |
44 | has barrel-shifter, so this implementation will be always used for this | |
45 | purpose. */ | |
06537f05 | 46 | #if !defined (__ARC601__) && defined (__ARC_BARREL_SHIFTER__) |
c0a99f02 AK |
47 | |
48 | /* To deal with alignment/loop issues, SMALL must be at least 2. */ | |
49 | #define SMALL 7 | |
50 | ||
51 | .global __strncpy_bzero | |
52 | .hidden __strncpy_bzero | |
53 | /* __strncpy_bzero provides the following interface to strncpy: | |
54 | r0: return value | |
55 | r2: zeroing length | |
56 | r3: zeroing start address | |
57 | No attempt is made here for __strncpy_memset to speed up aligned | |
58 | cases, because the copying of a string presumably leaves start address | |
59 | and length alignment for the zeroing randomly distributed. */ | |
60 | ||
06537f05 | 61 | #ifdef __ARCHS__ |
c0a99f02 AK |
62 | ENTRY (__dummy_memset) |
63 | #else | |
64 | ENTRY (memset) | |
65 | #endif | |
06537f05 | 66 | #if !defined (__ARC700__) && !defined (__ARCEM__) |
c0a99f02 AK |
67 | #undef SMALL |
68 | #define SMALL 8 /* Even faster if aligned. */ | |
69 | brls.d r2,SMALL,.Ltiny | |
70 | #endif | |
71 | mov_s r3,r0 | |
72 | or r12,r0,r2 | |
73 | bmsk.f r12,r12,1 | |
74 | extb_s r1,r1 | |
75 | asl r12,r1,8 | |
76 | beq.d .Laligned | |
77 | or_s r1,r1,r12 | |
06537f05 | 78 | #if defined (__ARC700__) || defined (__ARCEM__) |
c0a99f02 AK |
79 | brls r2,SMALL,.Ltiny |
80 | #endif | |
81 | .Lnot_tiny: | |
82 | add_s r12,r2,r0 | |
83 | stb r1,[r12,-1] | |
84 | bclr_l r12,r12,0 | |
85 | stw r1,[r12,-2] | |
86 | bmsk.f r12,r3,1 | |
87 | add_s r2,r2,r12 | |
88 | sub.ne r2,r2,4 | |
89 | stb.ab r1,[r3,1] | |
90 | bclr_s r3,r3,0 | |
91 | stw.ab r1,[r3,2] | |
92 | bclr_s r3,r3,1 | |
93 | .Laligned: ; This code address should be aligned for speed. | |
06537f05 | 94 | #if defined (__ARC700__) || defined (__ARCEM__) |
c0a99f02 AK |
95 | asl r12,r1,16 |
96 | lsr.f lp_count,r2,2 | |
97 | or_s r1,r1,r12 | |
98 | lpne .Loop_end | |
99 | st.ab r1,[r3,4] | |
100 | .Loop_end: | |
101 | j_s [blink] | |
102 | #else /* !__ARC700 */ | |
103 | lsr.f lp_count,r2,3 | |
104 | asl r12,r1,16 | |
105 | or_s r1,r1,r12 | |
106 | lpne .Loop_end | |
107 | st.ab r1,[r3,4] | |
108 | st.ab r1,[r3,4] | |
109 | .Loop_end: | |
110 | jcc [blink] | |
111 | j_s.d [blink] | |
112 | st_s r1,[r3] | |
113 | #endif /* !__ARC700 */ | |
114 | ||
06537f05 | 115 | #if defined (__ARC700__) || defined (__ARCEM__) |
c0a99f02 AK |
116 | .balign 4 |
117 | __strncpy_bzero: | |
118 | brhi.d r2,17,.Lnot_tiny | |
119 | mov_l r1,0 | |
120 | .Ltiny: | |
121 | mov.f lp_count,r2 | |
122 | lpne .Ltiny_end | |
123 | stb.ab r1,[r3,1] | |
124 | .Ltiny_end: | |
125 | j_s [blink] | |
126 | #else /* !__ARC700__ */ | |
127 | #if SMALL > 8 | |
128 | FIXME | |
129 | #endif | |
130 | .balign 4 | |
131 | __strncpy_bzero: | |
132 | brhi.d r2,8,.Lnot_tiny | |
133 | mov_s r1,0 | |
134 | .Ltiny: | |
135 | sub_s r2,r2,11 | |
136 | sub1 r12,pcl,r2 | |
137 | j_s [r12] | |
138 | stb_s r1,[r3,7] | |
139 | stb_s r1,[r3,6] | |
140 | stb_s r1,[r3,5] | |
141 | stb_s r1,[r3,4] | |
142 | stb_s r1,[r3,3] | |
143 | stb_s r1,[r3,2] | |
144 | stb_s r1,[r3,1] | |
145 | stb_s r1,[r3] | |
146 | j_s [blink] | |
147 | #endif /* !__ARC700 */ | |
06537f05 | 148 | #ifdef __ARCHS__ |
c0a99f02 AK |
149 | ENDFUNC (__dummy_memset) |
150 | #else | |
151 | ENDFUNC (memset) | |
152 | #endif | |
06537f05 | 153 | #endif /* !__ARC601__ && __ARC_BARREL_SHIFTER__ */ |
c0a99f02 AK |
154 | |
155 | #endif /* !__OPTIMIZE_SIZE__ && !PREFER_SIZE_OVER_SPEED */ |