1 /* Copyright (C) 2012-2019 Free Software Foundation, Inc.
2
3 This file is part of GCC.
4
5 GCC is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 GCC is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
14
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
18
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
23
24 /* This file must be kept in sync with newlib/libc/machine/visium/memset.c */
25
26 #include <stddef.h>
27 #include "memset.h"
28
29 #define SET_32_OBJECTS(out) \
30 do { \
31 out [0] = m0; \
32 out [1] = m0; \
33 out [2] = m0; \
34 out [3] = m0; \
35 out [4] = m0; \
36 out [5] = m0; \
37 out [6] = m0; \
38 out [7] = m0; \
39 out [8] = m0; \
40 out [9] = m0; \
41 out [10] = m0; \
42 out [11] = m0; \
43 out [12] = m0; \
44 out [13] = m0; \
45 out [14] = m0; \
46 out [15] = m0; \
47 out [16] = m0; \
48 out [17] = m0; \
49 out [18] = m0; \
50 out [19] = m0; \
51 out [20] = m0; \
52 out [21] = m0; \
53 out [22] = m0; \
54 out [23] = m0; \
55 out [24] = m0; \
56 out [25] = m0; \
57 out [26] = m0; \
58 out [27] = m0; \
59 out [28] = m0; \
60 out [29] = m0; \
61 out [30] = m0; \
62 out [31] = m0; \
63 out += 32; \
64 } while(0)
65
66 #define SET_16_OBJECTS(out) \
67 do { \
68 out [0] = m0; \
69 out [1] = m0; \
70 out [2] = m0; \
71 out [3] = m0; \
72 out [4] = m0; \
73 out [5] = m0; \
74 out [6] = m0; \
75 out [7] = m0; \
76 out [8] = m0; \
77 out [9] = m0; \
78 out [10] = m0; \
79 out [11] = m0; \
80 out [12] = m0; \
81 out [13] = m0; \
82 out [14] = m0; \
83 out [15] = m0; \
84 out += 16; \
85 } while(0)
86
87 #define SET_12_OBJECTS(out) \
88 do { \
89 out [0] = m0; \
90 out [1] = m0; \
91 out [2] = m0; \
92 out [3] = m0; \
93 out [4] = m0; \
94 out [5] = m0; \
95 out [6] = m0; \
96 out [7] = m0; \
97 out [8] = m0; \
98 out [9] = m0; \
99 out [10] = m0; \
100 out [11] = m0; \
101 out += 12; \
102 } while(0)
103
104 #define SET_11_OBJECTS(out) \
105 do { \
106 out [0] = m0; \
107 out [1] = m0; \
108 out [2] = m0; \
109 out [3] = m0; \
110 out [4] = m0; \
111 out [5] = m0; \
112 out [6] = m0; \
113 out [7] = m0; \
114 out [8] = m0; \
115 out [9] = m0; \
116 out [10] = m0; \
117 out += 11; \
118 } while(0)
119
120 #define SET_10_OBJECTS(out) \
121 do { \
122 out [0] = m0; \
123 out [1] = m0; \
124 out [2] = m0; \
125 out [3] = m0; \
126 out [4] = m0; \
127 out [5] = m0; \
128 out [6] = m0; \
129 out [7] = m0; \
130 out [8] = m0; \
131 out [9] = m0; \
132 out += 10; \
133 } while(0)
134
135 #define SET_9_OBJECTS(out) \
136 do { \
137 out [0] = m0; \
138 out [1] = m0; \
139 out [2] = m0; \
140 out [3] = m0; \
141 out [4] = m0; \
142 out [5] = m0; \
143 out [6] = m0; \
144 out [7] = m0; \
145 out [8] = m0; \
146 out += 9; \
147 } while(0)
148
149 #define SET_8_OBJECTS(out) \
150 do { \
151 out [0] = m0; \
152 out [1] = m0; \
153 out [2] = m0; \
154 out [3] = m0; \
155 out [4] = m0; \
156 out [5] = m0; \
157 out [6] = m0; \
158 out [7] = m0; \
159 out += 8; \
160 } while(0)
161
162 #define SET_7_OBJECTS(out) \
163 do { \
164 out [0] = m0; \
165 out [1] = m0; \
166 out [2] = m0; \
167 out [3] = m0; \
168 out [4] = m0; \
169 out [5] = m0; \
170 out [6] = m0; \
171 out += 7; \
172 } while(0)
173
174 #define SET_6_OBJECTS(out) \
175 do { \
176 out [0] = m0; \
177 out [1] = m0; \
178 out [2] = m0; \
179 out [3] = m0; \
180 out [4] = m0; \
181 out [5] = m0; \
182 out += 6; \
183 } while(0)
184
185 #define SET_5_OBJECTS(out) \
186 do { \
187 out [0] = m0; \
188 out [1] = m0; \
189 out [2] = m0; \
190 out [3] = m0; \
191 out [4] = m0; \
192 out += 5; \
193 } while(0)
194
195 #define SET_4_OBJECTS(out) \
196 do { \
197 out [0] = m0; \
198 out [1] = m0; \
199 out [2] = m0; \
200 out [3] = m0; \
201 out += 4; \
202 } while(0)
203
204 #define SET_3_OBJECTS(out) \
205 do { \
206 out [0] = m0; \
207 out [1] = m0; \
208 out [2] = m0; \
209 out += 3; \
210 } while(0)
211
212 #define SET_2_OBJECTS(out) \
213 do { \
214 out [0] = m0; \
215 out [1] = m0; \
216 out += 2; \
217 } while(0)
218
219 #define SET_1_OBJECT(out) \
220 do { \
221 out [0] = m0; \
222 out += 1; \
223 } while(0)
224
225
226 static inline void
__int_memset(void * __restrict s1,int val,size_t n)227 __int_memset (void *__restrict s1, int val, size_t n)
228 {
229 int value = n;
230 int loop_var;
231 int *out = s1;
232 int count;
233 int m0 = val;
234
235 /* This code currently give a stall for any value with a 1->2 in the low 5
236 bits, i.e. 1,2, 33,34 ? not acceptable! */
237 switch (value & 0x1f)
238 {
239 case 0:
240 break;
241 case 1:
242 SET_1_OBJECT (out);
243 break;
244 case 2:
245 SET_2_OBJECTS (out);
246 break;
247 case 3:
248 SET_3_OBJECTS (out);
249 break;
250 case 4:
251 SET_4_OBJECTS (out);
252 break;
253 case 5:
254 SET_5_OBJECTS (out);
255 break;
256 case 6:
257 SET_6_OBJECTS (out);
258 break;
259 case 7:
260 SET_7_OBJECTS (out);
261 break;
262 case 8:
263 SET_8_OBJECTS (out);
264 break;
265 case 9:
266 SET_9_OBJECTS (out);
267 break;
268 case 10:
269 SET_10_OBJECTS (out);
270 break;
271 case 11:
272 SET_11_OBJECTS (out);
273 break;
274 case 12:
275 SET_12_OBJECTS (out);
276 break;
277 case 13:
278 SET_9_OBJECTS (out);
279 SET_4_OBJECTS (out);
280 break;
281 case 14:
282 SET_12_OBJECTS (out);
283 SET_2_OBJECTS (out);
284 break;
285 case 15:
286 SET_11_OBJECTS (out);
287 SET_4_OBJECTS (out);
288 break;
289 case 16:
290 SET_16_OBJECTS (out);
291 break;
292 case 17:
293 SET_11_OBJECTS (out);
294 SET_6_OBJECTS (out);
295 break;
296 case 18:
297 SET_9_OBJECTS (out);
298 SET_9_OBJECTS (out);
299 break;
300 case 19:
301 SET_16_OBJECTS (out);
302 SET_3_OBJECTS (out);
303 break;
304 case 20:
305 SET_16_OBJECTS (out);
306 SET_4_OBJECTS (out);
307 break;
308 case 21:
309 SET_16_OBJECTS (out);
310 SET_5_OBJECTS (out);
311 break;
312 case 22:
313 SET_16_OBJECTS (out);
314 SET_6_OBJECTS (out);
315 break;
316 case 23:
317 SET_16_OBJECTS (out);
318 SET_7_OBJECTS (out);
319 break;
320 case 24:
321 SET_16_OBJECTS (out);
322 SET_8_OBJECTS (out);
323 break;
324 case 25:
325 SET_16_OBJECTS (out);
326 SET_9_OBJECTS (out);
327 break;
328 case 26:
329 SET_16_OBJECTS (out);
330 SET_10_OBJECTS (out);
331 break;
332 case 27:
333 SET_16_OBJECTS (out);
334 SET_11_OBJECTS (out);
335 break;
336 case 28:
337 SET_16_OBJECTS (out);
338 SET_8_OBJECTS (out);
339 SET_4_OBJECTS (out);
340 break;
341 case 29:
342 SET_16_OBJECTS (out);
343 SET_9_OBJECTS (out);
344 SET_4_OBJECTS (out);
345 break;
346 case 30:
347 SET_16_OBJECTS (out);
348 SET_12_OBJECTS (out);
349 SET_2_OBJECTS (out);
350 break;
351 case 31:
352 SET_16_OBJECTS (out);
353 SET_11_OBJECTS (out);
354 SET_4_OBJECTS (out);
355 break;
356 }
357
358 /* This loop governs the asmptoptic behaviour of this algorithm, for long
359 word copies. */
360 count = value >> 5;
361 for (loop_var = 0; loop_var < count; loop_var++)
362 SET_32_OBJECTS (out);
363 }
364
365 static inline void
__short_int_memset(void * __restrict s1,int val,size_t n)366 __short_int_memset (void *__restrict s1, int val, size_t n)
367 {
368 int value = n;
369 int loop_var;
370 int short *out = s1;
371 int count;
372 int m0 = val;
373
374 /* This code currently give a stall for any value with a 1->2 in the low 5
375 bits, i.e. 1,2, 33,34 ? not acceptable! */
376 switch (value & 0x1f)
377 {
378 case 0:
379 break;
380 case 1:
381 SET_1_OBJECT (out);
382 break;
383 case 2:
384 SET_2_OBJECTS (out);
385 break;
386 case 3:
387 SET_3_OBJECTS (out);
388 break;
389 case 4:
390 SET_4_OBJECTS (out);
391 break;
392 case 5:
393 SET_5_OBJECTS (out);
394 break;
395 case 6:
396 SET_6_OBJECTS (out);
397 break;
398 case 7:
399 SET_7_OBJECTS (out);
400 break;
401 case 8:
402 SET_8_OBJECTS (out);
403 break;
404 case 9:
405 SET_9_OBJECTS (out);
406 break;
407 case 10:
408 SET_10_OBJECTS (out);
409 break;
410 case 11:
411 SET_11_OBJECTS (out);
412 break;
413 case 12:
414 SET_12_OBJECTS (out);
415 break;
416 case 13:
417 SET_9_OBJECTS (out);
418 SET_4_OBJECTS (out);
419 break;
420 case 14:
421 SET_12_OBJECTS (out);
422 SET_2_OBJECTS (out);
423 break;
424 case 15:
425 SET_11_OBJECTS (out);
426 SET_4_OBJECTS (out);
427 break;
428 case 16:
429 SET_16_OBJECTS (out);
430 break;
431 case 17:
432 SET_11_OBJECTS (out);
433 SET_6_OBJECTS (out);
434 break;
435 case 18:
436 SET_9_OBJECTS (out);
437 SET_9_OBJECTS (out);
438 break;
439 case 19:
440 SET_16_OBJECTS (out);
441 SET_3_OBJECTS (out);
442 break;
443 case 20:
444 SET_16_OBJECTS (out);
445 SET_4_OBJECTS (out);
446 break;
447 case 21:
448 SET_16_OBJECTS (out);
449 SET_5_OBJECTS (out);
450 break;
451 case 22:
452 SET_16_OBJECTS (out);
453 SET_6_OBJECTS (out);
454 break;
455 case 23:
456 SET_16_OBJECTS (out);
457 SET_7_OBJECTS (out);
458 break;
459 case 24:
460 SET_16_OBJECTS (out);
461 SET_8_OBJECTS (out);
462 break;
463 case 25:
464 SET_16_OBJECTS (out);
465 SET_9_OBJECTS (out);
466 break;
467 case 26:
468 SET_16_OBJECTS (out);
469 SET_10_OBJECTS (out);
470 break;
471 case 27:
472 SET_16_OBJECTS (out);
473 SET_11_OBJECTS (out);
474 break;
475 case 28:
476 SET_16_OBJECTS (out);
477 SET_8_OBJECTS (out);
478 SET_4_OBJECTS (out);
479 break;
480 case 29:
481 SET_16_OBJECTS (out);
482 SET_9_OBJECTS (out);
483 SET_4_OBJECTS (out);
484 break;
485 case 30:
486 SET_16_OBJECTS (out);
487 SET_12_OBJECTS (out);
488 SET_2_OBJECTS (out);
489 break;
490 case 31:
491 SET_16_OBJECTS (out);
492 SET_11_OBJECTS (out);
493 SET_4_OBJECTS (out);
494 break;
495 }
496
497 /* This loop governs the asmptoptic behaviour of this algorithm, for long
498 word copies. */
499 count = value >> 5;
500 for (loop_var = 0; loop_var < count; loop_var++)
501 SET_32_OBJECTS (out);
502 }
503
504 static inline void
__byte_memset(void * __restrict s1,int val,size_t n)505 __byte_memset (void *__restrict s1, int val, size_t n)
506 {
507 int value = n;
508 int loop_var;
509 char *out = s1;
510 int count;
511 int m0 = val;
512
513 /* This code currently give a stall for any value with a 1->2 in the low 5
514 bits, i.e. 1,2, 33,34 ? not acceptable! */
515 switch (value & 0x1f)
516 {
517 case 0:
518 break;
519 case 1:
520 SET_1_OBJECT (out);
521 break;
522 case 2:
523 SET_2_OBJECTS (out);
524 break;
525 case 3:
526 SET_3_OBJECTS (out);
527 break;
528 case 4:
529 SET_4_OBJECTS (out);
530 break;
531 case 5:
532 SET_5_OBJECTS (out);
533 break;
534 case 6:
535 SET_6_OBJECTS (out);
536 break;
537 case 7:
538 SET_7_OBJECTS (out);
539 break;
540 case 8:
541 SET_8_OBJECTS (out);
542 break;
543 case 9:
544 SET_9_OBJECTS (out);
545 break;
546 case 10:
547 SET_10_OBJECTS (out);
548 break;
549 case 11:
550 SET_11_OBJECTS (out);
551 break;
552 case 12:
553 SET_12_OBJECTS (out);
554 break;
555 case 13:
556 SET_9_OBJECTS (out);
557 SET_4_OBJECTS (out);
558 break;
559 case 14:
560 SET_12_OBJECTS (out);
561 SET_2_OBJECTS (out);
562 break;
563 case 15:
564 SET_11_OBJECTS (out);
565 SET_4_OBJECTS (out);
566 break;
567 case 16:
568 SET_16_OBJECTS (out);
569 break;
570 case 17:
571 SET_11_OBJECTS (out);
572 SET_6_OBJECTS (out);
573 break;
574 case 18:
575 SET_9_OBJECTS (out);
576 SET_9_OBJECTS (out);
577 break;
578 case 19:
579 SET_16_OBJECTS (out);
580 SET_3_OBJECTS (out);
581 break;
582 case 20:
583 SET_16_OBJECTS (out);
584 SET_4_OBJECTS (out);
585 break;
586 case 21:
587 SET_16_OBJECTS (out);
588 SET_5_OBJECTS (out);
589 break;
590 case 22:
591 SET_16_OBJECTS (out);
592 SET_6_OBJECTS (out);
593 break;
594 case 23:
595 SET_16_OBJECTS (out);
596 SET_7_OBJECTS (out);
597 break;
598 case 24:
599 SET_16_OBJECTS (out);
600 SET_8_OBJECTS (out);
601 break;
602 case 25:
603 SET_16_OBJECTS (out);
604 SET_9_OBJECTS (out);
605 break;
606 case 26:
607 SET_16_OBJECTS (out);
608 SET_10_OBJECTS (out);
609 break;
610 case 27:
611 SET_16_OBJECTS (out);
612 SET_11_OBJECTS (out);
613 break;
614 case 28:
615 SET_16_OBJECTS (out);
616 SET_8_OBJECTS (out);
617 SET_4_OBJECTS (out);
618 break;
619 case 29:
620 SET_16_OBJECTS (out);
621 SET_9_OBJECTS (out);
622 SET_4_OBJECTS (out);
623 break;
624 case 30:
625 SET_16_OBJECTS (out);
626 SET_12_OBJECTS (out);
627 SET_2_OBJECTS (out);
628 break;
629 case 31:
630 SET_16_OBJECTS (out);
631 SET_11_OBJECTS (out);
632 SET_4_OBJECTS (out);
633 break;
634 }
635
636 /* This loop governs the asmptoptic behaviour of this algorithm, for long
637 word copies. */
638 count = value >> 5;
639 for (loop_var = 0; loop_var < count; loop_var++)
640 SET_32_OBJECTS (out);
641 }
642
643
644 /* Exposed interface. */
645
646 void
__long_int_memset(void * __restrict s,int c,size_t n)647 __long_int_memset (void *__restrict s, int c, size_t n)
648 {
649 int ic = (c << 24) + ((char) c << 16) + ((char) c << 8) + (char) c;
650 __int_memset (s, ic, n);
651 }
652
653 void
__wrd_memset(void * __restrict s,int c,size_t n)654 __wrd_memset (void *__restrict s, int c, size_t n)
655 {
656 int sc = ((c << 8) + (char) c);
657 __short_int_memset (s, sc, n);
658 }
659
660 void
__byt_memset(void * __restrict s,int c,size_t n)661 __byt_memset (void *__restrict s, int c, size_t n)
662 {
663 __byte_memset (s, c, n);
664 }
665