* ru.po: Update.
[official-gcc.git] / libgfortran / generated / maxloc1_4_i1.c
blob00cf9d4d095905ea2089b60c794de016a46d0719
1 /* Implementation of the MAXLOC intrinsic
2 Copyright (C) 2002-2016 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
5 This file is part of the GNU Fortran runtime library (libgfortran).
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.
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.
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.
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/>. */
26 #include "libgfortran.h"
27 #include <stdlib.h>
28 #include <assert.h>
29 #include <limits.h>
32 #if defined (HAVE_GFC_INTEGER_1) && defined (HAVE_GFC_INTEGER_4)
35 extern void maxloc1_4_i1 (gfc_array_i4 * const restrict,
36 gfc_array_i1 * const restrict, const index_type * const restrict);
37 export_proto(maxloc1_4_i1);
39 void
40 maxloc1_4_i1 (gfc_array_i4 * const restrict retarray,
41 gfc_array_i1 * const restrict array,
42 const index_type * const restrict pdim)
44 index_type count[GFC_MAX_DIMENSIONS];
45 index_type extent[GFC_MAX_DIMENSIONS];
46 index_type sstride[GFC_MAX_DIMENSIONS];
47 index_type dstride[GFC_MAX_DIMENSIONS];
48 const GFC_INTEGER_1 * restrict base;
49 GFC_INTEGER_4 * restrict dest;
50 index_type rank;
51 index_type n;
52 index_type len;
53 index_type delta;
54 index_type dim;
55 int continue_loop;
57 /* Make dim zero based to avoid confusion. */
58 dim = (*pdim) - 1;
59 rank = GFC_DESCRIPTOR_RANK (array) - 1;
61 len = GFC_DESCRIPTOR_EXTENT(array,dim);
62 if (len < 0)
63 len = 0;
64 delta = GFC_DESCRIPTOR_STRIDE(array,dim);
66 for (n = 0; n < dim; n++)
68 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
69 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
71 if (extent[n] < 0)
72 extent[n] = 0;
74 for (n = dim; n < rank; n++)
76 sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1);
77 extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
79 if (extent[n] < 0)
80 extent[n] = 0;
83 if (retarray->base_addr == NULL)
85 size_t alloc_size, str;
87 for (n = 0; n < rank; n++)
89 if (n == 0)
90 str = 1;
91 else
92 str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
94 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
98 retarray->offset = 0;
99 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
101 alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
103 retarray->base_addr = xmallocarray (alloc_size, sizeof (GFC_INTEGER_4));
104 if (alloc_size == 0)
106 /* Make sure we have a zero-sized array. */
107 GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
108 return;
112 else
114 if (rank != GFC_DESCRIPTOR_RANK (retarray))
115 runtime_error ("rank of return array incorrect in"
116 " MAXLOC intrinsic: is %ld, should be %ld",
117 (long int) (GFC_DESCRIPTOR_RANK (retarray)),
118 (long int) rank);
120 if (unlikely (compile_options.bounds_check))
121 bounds_ifunction_return ((array_t *) retarray, extent,
122 "return value", "MAXLOC");
125 for (n = 0; n < rank; n++)
127 count[n] = 0;
128 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
129 if (extent[n] <= 0)
130 return;
133 base = array->base_addr;
134 dest = retarray->base_addr;
136 continue_loop = 1;
137 while (continue_loop)
139 const GFC_INTEGER_1 * restrict src;
140 GFC_INTEGER_4 result;
141 src = base;
144 GFC_INTEGER_1 maxval;
145 #if defined (GFC_INTEGER_1_INFINITY)
146 maxval = -GFC_INTEGER_1_INFINITY;
147 #else
148 maxval = (-GFC_INTEGER_1_HUGE-1);
149 #endif
150 result = 1;
151 if (len <= 0)
152 *dest = 0;
153 else
155 for (n = 0; n < len; n++, src += delta)
158 #if defined (GFC_INTEGER_1_QUIET_NAN)
159 if (*src >= maxval)
161 maxval = *src;
162 result = (GFC_INTEGER_4)n + 1;
163 break;
166 for (; n < len; n++, src += delta)
168 #endif
169 if (*src > maxval)
171 maxval = *src;
172 result = (GFC_INTEGER_4)n + 1;
176 *dest = result;
179 /* Advance to the next element. */
180 count[0]++;
181 base += sstride[0];
182 dest += dstride[0];
183 n = 0;
184 while (count[n] == extent[n])
186 /* When we get to the end of a dimension, reset it and increment
187 the next dimension. */
188 count[n] = 0;
189 /* We could precalculate these products, but this is a less
190 frequently used path so probably not worth it. */
191 base -= sstride[n] * extent[n];
192 dest -= dstride[n] * extent[n];
193 n++;
194 if (n == rank)
196 /* Break out of the look. */
197 continue_loop = 0;
198 break;
200 else
202 count[n]++;
203 base += sstride[n];
204 dest += dstride[n];
211 extern void mmaxloc1_4_i1 (gfc_array_i4 * const restrict,
212 gfc_array_i1 * const restrict, const index_type * const restrict,
213 gfc_array_l1 * const restrict);
214 export_proto(mmaxloc1_4_i1);
216 void
217 mmaxloc1_4_i1 (gfc_array_i4 * const restrict retarray,
218 gfc_array_i1 * const restrict array,
219 const index_type * const restrict pdim,
220 gfc_array_l1 * const restrict mask)
222 index_type count[GFC_MAX_DIMENSIONS];
223 index_type extent[GFC_MAX_DIMENSIONS];
224 index_type sstride[GFC_MAX_DIMENSIONS];
225 index_type dstride[GFC_MAX_DIMENSIONS];
226 index_type mstride[GFC_MAX_DIMENSIONS];
227 GFC_INTEGER_4 * restrict dest;
228 const GFC_INTEGER_1 * restrict base;
229 const GFC_LOGICAL_1 * restrict mbase;
230 int rank;
231 int dim;
232 index_type n;
233 index_type len;
234 index_type delta;
235 index_type mdelta;
236 int mask_kind;
238 dim = (*pdim) - 1;
239 rank = GFC_DESCRIPTOR_RANK (array) - 1;
241 len = GFC_DESCRIPTOR_EXTENT(array,dim);
242 if (len <= 0)
243 return;
245 mbase = mask->base_addr;
247 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
249 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
250 #ifdef HAVE_GFC_LOGICAL_16
251 || mask_kind == 16
252 #endif
254 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
255 else
256 runtime_error ("Funny sized logical array");
258 delta = GFC_DESCRIPTOR_STRIDE(array,dim);
259 mdelta = GFC_DESCRIPTOR_STRIDE_BYTES(mask,dim);
261 for (n = 0; n < dim; n++)
263 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
264 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
265 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
267 if (extent[n] < 0)
268 extent[n] = 0;
271 for (n = dim; n < rank; n++)
273 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n + 1);
274 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n + 1);
275 extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
277 if (extent[n] < 0)
278 extent[n] = 0;
281 if (retarray->base_addr == NULL)
283 size_t alloc_size, str;
285 for (n = 0; n < rank; n++)
287 if (n == 0)
288 str = 1;
289 else
290 str= GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
292 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
296 alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
298 retarray->offset = 0;
299 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
301 if (alloc_size == 0)
303 /* Make sure we have a zero-sized array. */
304 GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
305 return;
307 else
308 retarray->base_addr = xmallocarray (alloc_size, sizeof (GFC_INTEGER_4));
311 else
313 if (rank != GFC_DESCRIPTOR_RANK (retarray))
314 runtime_error ("rank of return array incorrect in MAXLOC intrinsic");
316 if (unlikely (compile_options.bounds_check))
318 bounds_ifunction_return ((array_t *) retarray, extent,
319 "return value", "MAXLOC");
320 bounds_equal_extents ((array_t *) mask, (array_t *) array,
321 "MASK argument", "MAXLOC");
325 for (n = 0; n < rank; n++)
327 count[n] = 0;
328 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
329 if (extent[n] <= 0)
330 return;
333 dest = retarray->base_addr;
334 base = array->base_addr;
336 while (base)
338 const GFC_INTEGER_1 * restrict src;
339 const GFC_LOGICAL_1 * restrict msrc;
340 GFC_INTEGER_4 result;
341 src = base;
342 msrc = mbase;
345 GFC_INTEGER_1 maxval;
346 #if defined (GFC_INTEGER_1_INFINITY)
347 maxval = -GFC_INTEGER_1_INFINITY;
348 #else
349 maxval = (-GFC_INTEGER_1_HUGE-1);
350 #endif
351 #if defined (GFC_INTEGER_1_QUIET_NAN)
352 GFC_INTEGER_4 result2 = 0;
353 #endif
354 result = 0;
355 for (n = 0; n < len; n++, src += delta, msrc += mdelta)
358 if (*msrc)
360 #if defined (GFC_INTEGER_1_QUIET_NAN)
361 if (!result2)
362 result2 = (GFC_INTEGER_4)n + 1;
363 if (*src >= maxval)
364 #endif
366 maxval = *src;
367 result = (GFC_INTEGER_4)n + 1;
368 break;
372 #if defined (GFC_INTEGER_1_QUIET_NAN)
373 if (unlikely (n >= len))
374 result = result2;
375 else
376 #endif
377 for (; n < len; n++, src += delta, msrc += mdelta)
379 if (*msrc && *src > maxval)
381 maxval = *src;
382 result = (GFC_INTEGER_4)n + 1;
385 *dest = result;
387 /* Advance to the next element. */
388 count[0]++;
389 base += sstride[0];
390 mbase += mstride[0];
391 dest += dstride[0];
392 n = 0;
393 while (count[n] == extent[n])
395 /* When we get to the end of a dimension, reset it and increment
396 the next dimension. */
397 count[n] = 0;
398 /* We could precalculate these products, but this is a less
399 frequently used path so probably not worth it. */
400 base -= sstride[n] * extent[n];
401 mbase -= mstride[n] * extent[n];
402 dest -= dstride[n] * extent[n];
403 n++;
404 if (n == rank)
406 /* Break out of the look. */
407 base = NULL;
408 break;
410 else
412 count[n]++;
413 base += sstride[n];
414 mbase += mstride[n];
415 dest += dstride[n];
422 extern void smaxloc1_4_i1 (gfc_array_i4 * const restrict,
423 gfc_array_i1 * const restrict, const index_type * const restrict,
424 GFC_LOGICAL_4 *);
425 export_proto(smaxloc1_4_i1);
427 void
428 smaxloc1_4_i1 (gfc_array_i4 * const restrict retarray,
429 gfc_array_i1 * const restrict array,
430 const index_type * const restrict pdim,
431 GFC_LOGICAL_4 * mask)
433 index_type count[GFC_MAX_DIMENSIONS];
434 index_type extent[GFC_MAX_DIMENSIONS];
435 index_type dstride[GFC_MAX_DIMENSIONS];
436 GFC_INTEGER_4 * restrict dest;
437 index_type rank;
438 index_type n;
439 index_type dim;
442 if (*mask)
444 maxloc1_4_i1 (retarray, array, pdim);
445 return;
447 /* Make dim zero based to avoid confusion. */
448 dim = (*pdim) - 1;
449 rank = GFC_DESCRIPTOR_RANK (array) - 1;
451 for (n = 0; n < dim; n++)
453 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
455 if (extent[n] <= 0)
456 extent[n] = 0;
459 for (n = dim; n < rank; n++)
461 extent[n] =
462 GFC_DESCRIPTOR_EXTENT(array,n + 1);
464 if (extent[n] <= 0)
465 extent[n] = 0;
468 if (retarray->base_addr == NULL)
470 size_t alloc_size, str;
472 for (n = 0; n < rank; n++)
474 if (n == 0)
475 str = 1;
476 else
477 str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
479 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
483 retarray->offset = 0;
484 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
486 alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
488 if (alloc_size == 0)
490 /* Make sure we have a zero-sized array. */
491 GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
492 return;
494 else
495 retarray->base_addr = xmallocarray (alloc_size, sizeof (GFC_INTEGER_4));
497 else
499 if (rank != GFC_DESCRIPTOR_RANK (retarray))
500 runtime_error ("rank of return array incorrect in"
501 " MAXLOC intrinsic: is %ld, should be %ld",
502 (long int) (GFC_DESCRIPTOR_RANK (retarray)),
503 (long int) rank);
505 if (unlikely (compile_options.bounds_check))
507 for (n=0; n < rank; n++)
509 index_type ret_extent;
511 ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,n);
512 if (extent[n] != ret_extent)
513 runtime_error ("Incorrect extent in return value of"
514 " MAXLOC intrinsic in dimension %ld:"
515 " is %ld, should be %ld", (long int) n + 1,
516 (long int) ret_extent, (long int) extent[n]);
521 for (n = 0; n < rank; n++)
523 count[n] = 0;
524 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
527 dest = retarray->base_addr;
529 while(1)
531 *dest = 0;
532 count[0]++;
533 dest += dstride[0];
534 n = 0;
535 while (count[n] == extent[n])
537 /* When we get to the end of a dimension, reset it and increment
538 the next dimension. */
539 count[n] = 0;
540 /* We could precalculate these products, but this is a less
541 frequently used path so probably not worth it. */
542 dest -= dstride[n] * extent[n];
543 n++;
544 if (n == rank)
545 return;
546 else
548 count[n]++;
549 dest += dstride[n];
555 #endif