]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgfortran/generated/minval1_s4.c
Add missing config/i386/zn4zn5.md file
[thirdparty/gcc.git] / libgfortran / generated / minval1_s4.c
1 /* Implementation of the MAXVAL intrinsic
2 Copyright (C) 2017-2024 Free Software Foundation, Inc.
3 Contributed by Thomas Koenig
4
5 This file is part of the GNU Fortran runtime library (libgfortran).
6
7 Libgfortran is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
11
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
25
26 #include "libgfortran.h"
27
28
29 #if defined (HAVE_GFC_UINTEGER_4) && defined (HAVE_GFC_UINTEGER_4)
30
31 #include <string.h>
32 #include <assert.h>
33
34 static inline int
35 compare_fcn (const GFC_UINTEGER_4 *a, const GFC_UINTEGER_4 *b, gfc_charlen_type n)
36 {
37 if (sizeof (GFC_UINTEGER_4) == 1)
38 return memcmp (a, b, n);
39 else
40 return memcmp_char4 (a, b, n);
41 }
42
43 extern void minval1_s4 (gfc_array_s4 * const restrict,
44 gfc_charlen_type, gfc_array_s4 * const restrict,
45 const index_type * const restrict, gfc_charlen_type);
46 export_proto(minval1_s4);
47
48 void
49 minval1_s4 (gfc_array_s4 * const restrict retarray,
50 gfc_charlen_type xlen, gfc_array_s4 * const restrict array,
51 const index_type * const restrict pdim, gfc_charlen_type string_len)
52 {
53 index_type count[GFC_MAX_DIMENSIONS];
54 index_type extent[GFC_MAX_DIMENSIONS];
55 index_type sstride[GFC_MAX_DIMENSIONS];
56 index_type dstride[GFC_MAX_DIMENSIONS];
57 const GFC_UINTEGER_4 * restrict base;
58 GFC_UINTEGER_4 * restrict dest;
59 index_type rank;
60 index_type n;
61 index_type len;
62 index_type delta;
63 index_type dim;
64 int continue_loop;
65
66 assert (xlen == string_len);
67 /* Make dim zero based to avoid confusion. */
68 rank = GFC_DESCRIPTOR_RANK (array) - 1;
69 dim = (*pdim) - 1;
70
71 if (unlikely (dim < 0 || dim > rank))
72 {
73 runtime_error ("Dim argument incorrect in MINVAL intrinsic: "
74 "is %ld, should be between 1 and %ld",
75 (long int) dim + 1, (long int) rank + 1);
76 }
77
78 len = GFC_DESCRIPTOR_EXTENT(array,dim);
79 if (len < 0)
80 len = 0;
81
82 delta = GFC_DESCRIPTOR_STRIDE(array,dim) * string_len;
83
84 for (n = 0; n < dim; n++)
85 {
86 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n) * string_len;
87 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
88
89 if (extent[n] < 0)
90 extent[n] = 0;
91 }
92 for (n = dim; n < rank; n++)
93 {
94 sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1) * string_len;
95 extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
96
97 if (extent[n] < 0)
98 extent[n] = 0;
99 }
100
101 if (retarray->base_addr == NULL)
102 {
103 size_t alloc_size, str;
104
105 for (n = 0; n < rank; n++)
106 {
107 if (n == 0)
108 str = 1;
109 else
110 str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
111
112 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
113
114 }
115
116 retarray->offset = 0;
117 retarray->dtype.rank = rank;
118
119 alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1]
120 * string_len;
121
122 retarray->base_addr = xmallocarray (alloc_size, sizeof (GFC_UINTEGER_4));
123 if (alloc_size == 0)
124 return;
125 }
126 else
127 {
128 if (rank != GFC_DESCRIPTOR_RANK (retarray))
129 runtime_error ("rank of return array incorrect in"
130 " MINVAL intrinsic: is %ld, should be %ld",
131 (long int) (GFC_DESCRIPTOR_RANK (retarray)),
132 (long int) rank);
133
134 if (unlikely (compile_options.bounds_check))
135 bounds_ifunction_return ((array_t *) retarray, extent,
136 "return value", "MINVAL");
137 }
138
139 for (n = 0; n < rank; n++)
140 {
141 count[n] = 0;
142 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n) * string_len;
143 if (extent[n] <= 0)
144 return;
145 }
146
147 base = array->base_addr;
148 dest = retarray->base_addr;
149
150 continue_loop = 1;
151 while (continue_loop)
152 {
153 const GFC_UINTEGER_4 * restrict src;
154 src = base;
155 {
156
157 const GFC_UINTEGER_4 *retval;
158 retval = base;
159 if (len <= 0)
160 memset (dest, 255, sizeof (*dest) * string_len);
161 else
162 {
163 for (n = 0; n < len; n++, src += delta)
164 {
165
166 if (compare_fcn (src, retval, string_len) < 0)
167 {
168 retval = src;
169 }
170 }
171
172 memcpy (dest, retval, sizeof (*dest) * string_len);
173 }
174 }
175 /* Advance to the next element. */
176 count[0]++;
177 base += sstride[0];
178 dest += dstride[0];
179 n = 0;
180 while (count[n] == extent[n])
181 {
182 /* When we get to the end of a dimension, reset it and increment
183 the next dimension. */
184 count[n] = 0;
185 /* We could precalculate these products, but this is a less
186 frequently used path so probably not worth it. */
187 base -= sstride[n] * extent[n];
188 dest -= dstride[n] * extent[n];
189 n++;
190 if (n >= rank)
191 {
192 /* Break out of the loop. */
193 continue_loop = 0;
194 break;
195 }
196 else
197 {
198 count[n]++;
199 base += sstride[n];
200 dest += dstride[n];
201 }
202 }
203 }
204 }
205
206
207 extern void mminval1_s4 (gfc_array_s4 * const restrict,
208 gfc_charlen_type, gfc_array_s4 * const restrict,
209 const index_type * const restrict,
210 gfc_array_l1 * const restrict, gfc_charlen_type);
211 export_proto(mminval1_s4);
212
213 void
214 mminval1_s4 (gfc_array_s4 * const restrict retarray,
215 gfc_charlen_type xlen, gfc_array_s4 * const restrict array,
216 const index_type * const restrict pdim,
217 gfc_array_l1 * const restrict mask,
218 gfc_charlen_type string_len)
219
220 {
221 index_type count[GFC_MAX_DIMENSIONS];
222 index_type extent[GFC_MAX_DIMENSIONS];
223 index_type sstride[GFC_MAX_DIMENSIONS];
224 index_type dstride[GFC_MAX_DIMENSIONS];
225 index_type mstride[GFC_MAX_DIMENSIONS];
226 GFC_UINTEGER_4 * restrict dest;
227 const GFC_UINTEGER_4 * restrict base;
228 const GFC_LOGICAL_1 * restrict mbase;
229 index_type rank;
230 index_type dim;
231 index_type n;
232 index_type len;
233 index_type delta;
234 index_type mdelta;
235 int mask_kind;
236
237 if (mask == NULL)
238 {
239 minval1_s4 (retarray, xlen, array, pdim, string_len);
240 return;
241 }
242
243 assert (xlen == string_len);
244
245 dim = (*pdim) - 1;
246 rank = GFC_DESCRIPTOR_RANK (array) - 1;
247
248 if (unlikely (dim < 0 || dim > rank))
249 {
250 runtime_error ("Dim argument incorrect in MINVAL intrinsic: "
251 "is %ld, should be between 1 and %ld",
252 (long int) dim + 1, (long int) rank + 1);
253 }
254
255 len = GFC_DESCRIPTOR_EXTENT(array,dim);
256 if (len < 0)
257 len = 0;
258
259 mbase = mask->base_addr;
260
261 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
262
263 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
264 #ifdef HAVE_GFC_LOGICAL_16
265 || mask_kind == 16
266 #endif
267 )
268 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
269 else
270 runtime_error ("Funny sized logical array");
271
272 delta = GFC_DESCRIPTOR_STRIDE(array,dim) * string_len;
273 mdelta = GFC_DESCRIPTOR_STRIDE_BYTES(mask,dim);
274
275 for (n = 0; n < dim; n++)
276 {
277 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n) * string_len;
278 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
279 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
280
281 if (extent[n] < 0)
282 extent[n] = 0;
283
284 }
285 for (n = dim; n < rank; n++)
286 {
287 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n + 1) * string_len;
288 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n + 1);
289 extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
290
291 if (extent[n] < 0)
292 extent[n] = 0;
293 }
294
295 if (retarray->base_addr == NULL)
296 {
297 size_t alloc_size, str;
298
299 for (n = 0; n < rank; n++)
300 {
301 if (n == 0)
302 str = 1;
303 else
304 str= GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
305
306 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
307
308 }
309
310 alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1]
311 * string_len;
312
313 retarray->offset = 0;
314 retarray->dtype.rank = rank;
315
316 retarray->base_addr = xmallocarray (alloc_size, sizeof (GFC_UINTEGER_4));
317 if (alloc_size == 0)
318 return;
319 }
320 else
321 {
322 if (rank != GFC_DESCRIPTOR_RANK (retarray))
323 runtime_error ("rank of return array incorrect in MINVAL intrinsic");
324
325 if (unlikely (compile_options.bounds_check))
326 {
327 bounds_ifunction_return ((array_t *) retarray, extent,
328 "return value", "MINVAL");
329 bounds_equal_extents ((array_t *) mask, (array_t *) array,
330 "MASK argument", "MINVAL");
331 }
332 }
333
334 for (n = 0; n < rank; n++)
335 {
336 count[n] = 0;
337 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n) * string_len;
338 if (extent[n] <= 0)
339 return;
340 }
341
342 dest = retarray->base_addr;
343 base = array->base_addr;
344
345 while (base)
346 {
347 const GFC_UINTEGER_4 * restrict src;
348 const GFC_LOGICAL_1 * restrict msrc;
349
350 src = base;
351 msrc = mbase;
352 {
353
354 const GFC_UINTEGER_4 *retval;
355 memset (dest, 255, sizeof (*dest) * string_len);
356 retval = dest;
357 for (n = 0; n < len; n++, src += delta, msrc += mdelta)
358 {
359
360 if (*msrc)
361 {
362 retval = src;
363 break;
364 }
365 }
366 for (; n < len; n++, src += delta, msrc += mdelta)
367 {
368 if (*msrc && compare_fcn (src, retval, string_len) < 0)
369 {
370 retval = src;
371 }
372
373 }
374 memcpy (dest, retval, sizeof (*dest) * string_len);
375 }
376 /* Advance to the next element. */
377 count[0]++;
378 base += sstride[0];
379 mbase += mstride[0];
380 dest += dstride[0];
381 n = 0;
382 while (count[n] == extent[n])
383 {
384 /* When we get to the end of a dimension, reset it and increment
385 the next dimension. */
386 count[n] = 0;
387 /* We could precalculate these products, but this is a less
388 frequently used path so probably not worth it. */
389 base -= sstride[n] * extent[n];
390 mbase -= mstride[n] * extent[n];
391 dest -= dstride[n] * extent[n];
392 n++;
393 if (n >= rank)
394 {
395 /* Break out of the loop. */
396 base = NULL;
397 break;
398 }
399 else
400 {
401 count[n]++;
402 base += sstride[n];
403 mbase += mstride[n];
404 dest += dstride[n];
405 }
406 }
407 }
408 }
409
410
411 void sminval1_s4 (gfc_array_s4 * const restrict,
412 gfc_charlen_type, gfc_array_s4 * const restrict,
413 const index_type * const restrict,
414 GFC_LOGICAL_4 *, gfc_charlen_type);
415
416 export_proto(sminval1_s4);
417
418 void
419 sminval1_s4 (gfc_array_s4 * const restrict retarray,
420 gfc_charlen_type xlen, gfc_array_s4 * const restrict array,
421 const index_type * const restrict pdim,
422 GFC_LOGICAL_4 *mask, gfc_charlen_type string_len)
423
424 {
425 index_type count[GFC_MAX_DIMENSIONS];
426 index_type extent[GFC_MAX_DIMENSIONS];
427 index_type dstride[GFC_MAX_DIMENSIONS];
428 GFC_UINTEGER_4 * restrict dest;
429 index_type rank;
430 index_type n;
431 index_type dim;
432
433
434 if (mask == NULL || *mask)
435 {
436 minval1_s4 (retarray, xlen, array, pdim, string_len);
437 return;
438 }
439 /* Make dim zero based to avoid confusion. */
440 dim = (*pdim) - 1;
441 rank = GFC_DESCRIPTOR_RANK (array) - 1;
442
443 if (unlikely (dim < 0 || dim > rank))
444 {
445 runtime_error ("Dim argument incorrect in MINVAL intrinsic: "
446 "is %ld, should be between 1 and %ld",
447 (long int) dim + 1, (long int) rank + 1);
448 }
449
450 for (n = 0; n < dim; n++)
451 {
452 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
453
454 if (extent[n] <= 0)
455 extent[n] = 0;
456 }
457
458 for (n = dim; n < rank; n++)
459 {
460 extent[n] =
461 GFC_DESCRIPTOR_EXTENT(array,n + 1);
462
463 if (extent[n] <= 0)
464 extent[n] = 0;
465 }
466
467 if (retarray->base_addr == NULL)
468 {
469 size_t alloc_size, str;
470
471 for (n = 0; n < rank; n++)
472 {
473 if (n == 0)
474 str = 1;
475 else
476 str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
477
478 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
479
480 }
481
482 retarray->offset = 0;
483 retarray->dtype.rank = rank;
484
485 alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1]
486 * string_len;
487
488 retarray->base_addr = xmallocarray (alloc_size, sizeof (GFC_UINTEGER_4));
489 if (alloc_size == 0)
490 return;
491 }
492 else
493 {
494 if (rank != GFC_DESCRIPTOR_RANK (retarray))
495 runtime_error ("rank of return array incorrect in"
496 " MINVAL intrinsic: is %ld, should be %ld",
497 (long int) (GFC_DESCRIPTOR_RANK (retarray)),
498 (long int) rank);
499
500 if (unlikely (compile_options.bounds_check))
501 {
502 for (n=0; n < rank; n++)
503 {
504 index_type ret_extent;
505
506 ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,n);
507 if (extent[n] != ret_extent)
508 runtime_error ("Incorrect extent in return value of"
509 " MINVAL intrinsic in dimension %ld:"
510 " is %ld, should be %ld", (long int) n + 1,
511 (long int) ret_extent, (long int) extent[n]);
512 }
513 }
514 }
515
516 for (n = 0; n < rank; n++)
517 {
518 count[n] = 0;
519 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n) * string_len;
520 }
521
522 dest = retarray->base_addr;
523
524 while(1)
525 {
526 memset (dest, 255, sizeof (*dest) * string_len);
527 count[0]++;
528 dest += dstride[0];
529 n = 0;
530 while (count[n] == extent[n])
531 {
532 /* When we get to the end of a dimension, reset it and increment
533 the next dimension. */
534 count[n] = 0;
535 /* We could precalculate these products, but this is a less
536 frequently used path so probably not worth it. */
537 dest -= dstride[n] * extent[n];
538 n++;
539 if (n >= rank)
540 return;
541 else
542 {
543 count[n]++;
544 dest += dstride[n];
545 }
546 }
547 }
548 }
549
550 #endif