1 /* Copyright (C) 2012-2022 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