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