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)	\
30do {				\
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)	\
67do {				\
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)	\
88do {				\
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)	\
105do {				\
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)	\
121do {				\
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)	\
136do {				\
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)	\
150do {				\
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)	\
163do {				\
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)	\
175do {				\
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)	\
186do {				\
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)	\
196do {				\
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)	\
205do {				\
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)	\
213do {				\
214  out [0] = m0;			\
215  out [1] = m0;			\
216  out += 2;			\
217} while(0)
218
219#define SET_1_OBJECT(out)	\
220do {				\
221  out [0] = m0;			\
222  out += 1;			\
223} while(0)
224
225
226static inline void
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
365static inline void
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
504static inline void
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
646void
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
653void
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
660void
661__byt_memset (void *__restrict s, int c, size_t n)
662{
663  __byte_memset (s, c, n);
664}
665