]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libgfortran/generated/maxloc1_4_i2.c
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"
31 #if defined (HAVE_GFC_INTEGER_2) && defined (HAVE_GFC_INTEGER_4)
34 extern void maxloc1_4_i2 (gfc_array_i4
* const restrict
,
35 gfc_array_i2
* const restrict
, const index_type
* const restrict
);
36 export_proto(maxloc1_4_i2
);
39 maxloc1_4_i2 (gfc_array_i4
* const restrict retarray
,
40 gfc_array_i2
* const restrict array
,
41 const index_type
* const restrict pdim
)
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
];
47 const GFC_INTEGER_2
* restrict base
;
48 GFC_INTEGER_4
* restrict dest
;
56 /* Make dim zero based to avoid confusion. */
58 rank
= GFC_DESCRIPTOR_RANK (array
) - 1;
60 len
= GFC_DESCRIPTOR_EXTENT(array
,dim
);
63 delta
= GFC_DESCRIPTOR_STRIDE(array
,dim
);
65 for (n
= 0; n
< dim
; n
++)
67 sstride
[n
] = GFC_DESCRIPTOR_STRIDE(array
,n
);
68 extent
[n
] = GFC_DESCRIPTOR_EXTENT(array
,n
);
73 for (n
= dim
; n
< rank
; n
++)
75 sstride
[n
] = GFC_DESCRIPTOR_STRIDE(array
, n
+ 1);
76 extent
[n
] = GFC_DESCRIPTOR_EXTENT(array
, n
+ 1);
82 if (retarray
->base_addr
== NULL
)
84 size_t alloc_size
, str
;
86 for (n
= 0; n
< rank
; n
++)
91 str
= GFC_DESCRIPTOR_STRIDE(retarray
,n
-1) * extent
[n
-1];
93 GFC_DIMENSION_SET(retarray
->dim
[n
], 0, extent
[n
] - 1, str
);
98 retarray
->dtype
= (array
->dtype
& ~GFC_DTYPE_RANK_MASK
) | rank
;
100 alloc_size
= GFC_DESCRIPTOR_STRIDE(retarray
,rank
-1) * extent
[rank
-1];
102 retarray
->base_addr
= xmallocarray (alloc_size
, sizeof (GFC_INTEGER_4
));
105 /* Make sure we have a zero-sized array. */
106 GFC_DIMENSION_SET(retarray
->dim
[0], 0, -1, 1);
113 if (rank
!= GFC_DESCRIPTOR_RANK (retarray
))
114 runtime_error ("rank of return array incorrect in"
115 " MAXLOC intrinsic: is %ld, should be %ld",
116 (long int) (GFC_DESCRIPTOR_RANK (retarray
)),
119 if (unlikely (compile_options
.bounds_check
))
120 bounds_ifunction_return ((array_t
*) retarray
, extent
,
121 "return value", "MAXLOC");
124 for (n
= 0; n
< rank
; n
++)
127 dstride
[n
] = GFC_DESCRIPTOR_STRIDE(retarray
,n
);
132 base
= array
->base_addr
;
133 dest
= retarray
->base_addr
;
136 while (continue_loop
)
138 const GFC_INTEGER_2
* restrict src
;
139 GFC_INTEGER_4 result
;
143 GFC_INTEGER_2 maxval
;
144 #if defined (GFC_INTEGER_2_INFINITY)
145 maxval
= -GFC_INTEGER_2_INFINITY
;
147 maxval
= (-GFC_INTEGER_2_HUGE
-1);
154 for (n
= 0; n
< len
; n
++, src
+= delta
)
157 #if defined (GFC_INTEGER_2_QUIET_NAN)
161 result
= (GFC_INTEGER_4
)n
+ 1;
165 for (; n
< len
; n
++, src
+= delta
)
171 result
= (GFC_INTEGER_4
)n
+ 1;
178 /* Advance to the next element. */
183 while (count
[n
] == extent
[n
])
185 /* When we get to the end of a dimension, reset it and increment
186 the next dimension. */
188 /* We could precalculate these products, but this is a less
189 frequently used path so probably not worth it. */
190 base
-= sstride
[n
] * extent
[n
];
191 dest
-= dstride
[n
] * extent
[n
];
195 /* Break out of the look. */
210 extern void mmaxloc1_4_i2 (gfc_array_i4
* const restrict
,
211 gfc_array_i2
* const restrict
, const index_type
* const restrict
,
212 gfc_array_l1
* const restrict
);
213 export_proto(mmaxloc1_4_i2
);
216 mmaxloc1_4_i2 (gfc_array_i4
* const restrict retarray
,
217 gfc_array_i2
* const restrict array
,
218 const index_type
* const restrict pdim
,
219 gfc_array_l1
* const restrict mask
)
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_INTEGER_4
* restrict dest
;
227 const GFC_INTEGER_2
* restrict base
;
228 const GFC_LOGICAL_1
* restrict mbase
;
238 rank
= GFC_DESCRIPTOR_RANK (array
) - 1;
240 len
= GFC_DESCRIPTOR_EXTENT(array
,dim
);
244 mbase
= mask
->base_addr
;
246 mask_kind
= GFC_DESCRIPTOR_SIZE (mask
);
248 if (mask_kind
== 1 || mask_kind
== 2 || mask_kind
== 4 || mask_kind
== 8
249 #ifdef HAVE_GFC_LOGICAL_16
253 mbase
= GFOR_POINTER_TO_L1 (mbase
, mask_kind
);
255 runtime_error ("Funny sized logical array");
257 delta
= GFC_DESCRIPTOR_STRIDE(array
,dim
);
258 mdelta
= GFC_DESCRIPTOR_STRIDE_BYTES(mask
,dim
);
260 for (n
= 0; n
< dim
; n
++)
262 sstride
[n
] = GFC_DESCRIPTOR_STRIDE(array
,n
);
263 mstride
[n
] = GFC_DESCRIPTOR_STRIDE_BYTES(mask
,n
);
264 extent
[n
] = GFC_DESCRIPTOR_EXTENT(array
,n
);
270 for (n
= dim
; n
< rank
; n
++)
272 sstride
[n
] = GFC_DESCRIPTOR_STRIDE(array
,n
+ 1);
273 mstride
[n
] = GFC_DESCRIPTOR_STRIDE_BYTES(mask
, n
+ 1);
274 extent
[n
] = GFC_DESCRIPTOR_EXTENT(array
, n
+ 1);
280 if (retarray
->base_addr
== NULL
)
282 size_t alloc_size
, str
;
284 for (n
= 0; n
< rank
; n
++)
289 str
= GFC_DESCRIPTOR_STRIDE(retarray
,n
-1) * extent
[n
-1];
291 GFC_DIMENSION_SET(retarray
->dim
[n
], 0, extent
[n
] - 1, str
);
295 alloc_size
= GFC_DESCRIPTOR_STRIDE(retarray
,rank
-1) * extent
[rank
-1];
297 retarray
->offset
= 0;
298 retarray
->dtype
= (array
->dtype
& ~GFC_DTYPE_RANK_MASK
) | rank
;
302 /* Make sure we have a zero-sized array. */
303 GFC_DIMENSION_SET(retarray
->dim
[0], 0, -1, 1);
307 retarray
->base_addr
= xmallocarray (alloc_size
, sizeof (GFC_INTEGER_4
));
312 if (rank
!= GFC_DESCRIPTOR_RANK (retarray
))
313 runtime_error ("rank of return array incorrect in MAXLOC intrinsic");
315 if (unlikely (compile_options
.bounds_check
))
317 bounds_ifunction_return ((array_t
*) retarray
, extent
,
318 "return value", "MAXLOC");
319 bounds_equal_extents ((array_t
*) mask
, (array_t
*) array
,
320 "MASK argument", "MAXLOC");
324 for (n
= 0; n
< rank
; n
++)
327 dstride
[n
] = GFC_DESCRIPTOR_STRIDE(retarray
,n
);
332 dest
= retarray
->base_addr
;
333 base
= array
->base_addr
;
337 const GFC_INTEGER_2
* restrict src
;
338 const GFC_LOGICAL_1
* restrict msrc
;
339 GFC_INTEGER_4 result
;
344 GFC_INTEGER_2 maxval
;
345 #if defined (GFC_INTEGER_2_INFINITY)
346 maxval
= -GFC_INTEGER_2_INFINITY
;
348 maxval
= (-GFC_INTEGER_2_HUGE
-1);
350 #if defined (GFC_INTEGER_2_QUIET_NAN)
351 GFC_INTEGER_4 result2
= 0;
354 for (n
= 0; n
< len
; n
++, src
+= delta
, msrc
+= mdelta
)
359 #if defined (GFC_INTEGER_2_QUIET_NAN)
361 result2
= (GFC_INTEGER_4
)n
+ 1;
366 result
= (GFC_INTEGER_4
)n
+ 1;
371 #if defined (GFC_INTEGER_2_QUIET_NAN)
372 if (unlikely (n
>= len
))
376 for (; n
< len
; n
++, src
+= delta
, msrc
+= mdelta
)
378 if (*msrc
&& *src
> maxval
)
381 result
= (GFC_INTEGER_4
)n
+ 1;
386 /* Advance to the next element. */
392 while (count
[n
] == extent
[n
])
394 /* When we get to the end of a dimension, reset it and increment
395 the next dimension. */
397 /* We could precalculate these products, but this is a less
398 frequently used path so probably not worth it. */
399 base
-= sstride
[n
] * extent
[n
];
400 mbase
-= mstride
[n
] * extent
[n
];
401 dest
-= dstride
[n
] * extent
[n
];
405 /* Break out of the look. */
421 extern void smaxloc1_4_i2 (gfc_array_i4
* const restrict
,
422 gfc_array_i2
* const restrict
, const index_type
* const restrict
,
424 export_proto(smaxloc1_4_i2
);
427 smaxloc1_4_i2 (gfc_array_i4
* const restrict retarray
,
428 gfc_array_i2
* const restrict array
,
429 const index_type
* const restrict pdim
,
430 GFC_LOGICAL_4
* mask
)
432 index_type count
[GFC_MAX_DIMENSIONS
];
433 index_type extent
[GFC_MAX_DIMENSIONS
];
434 index_type dstride
[GFC_MAX_DIMENSIONS
];
435 GFC_INTEGER_4
* restrict dest
;
443 maxloc1_4_i2 (retarray
, array
, pdim
);
446 /* Make dim zero based to avoid confusion. */
448 rank
= GFC_DESCRIPTOR_RANK (array
) - 1;
450 for (n
= 0; n
< dim
; n
++)
452 extent
[n
] = GFC_DESCRIPTOR_EXTENT(array
,n
);
458 for (n
= dim
; n
< rank
; n
++)
461 GFC_DESCRIPTOR_EXTENT(array
,n
+ 1);
467 if (retarray
->base_addr
== NULL
)
469 size_t alloc_size
, str
;
471 for (n
= 0; n
< rank
; n
++)
476 str
= GFC_DESCRIPTOR_STRIDE(retarray
,n
-1) * extent
[n
-1];
478 GFC_DIMENSION_SET(retarray
->dim
[n
], 0, extent
[n
] - 1, str
);
482 retarray
->offset
= 0;
483 retarray
->dtype
= (array
->dtype
& ~GFC_DTYPE_RANK_MASK
) | rank
;
485 alloc_size
= GFC_DESCRIPTOR_STRIDE(retarray
,rank
-1) * extent
[rank
-1];
489 /* Make sure we have a zero-sized array. */
490 GFC_DIMENSION_SET(retarray
->dim
[0], 0, -1, 1);
494 retarray
->base_addr
= xmallocarray (alloc_size
, sizeof (GFC_INTEGER_4
));
498 if (rank
!= GFC_DESCRIPTOR_RANK (retarray
))
499 runtime_error ("rank of return array incorrect in"
500 " MAXLOC intrinsic: is %ld, should be %ld",
501 (long int) (GFC_DESCRIPTOR_RANK (retarray
)),
504 if (unlikely (compile_options
.bounds_check
))
506 for (n
=0; n
< rank
; n
++)
508 index_type ret_extent
;
510 ret_extent
= GFC_DESCRIPTOR_EXTENT(retarray
,n
);
511 if (extent
[n
] != ret_extent
)
512 runtime_error ("Incorrect extent in return value of"
513 " MAXLOC intrinsic in dimension %ld:"
514 " is %ld, should be %ld", (long int) n
+ 1,
515 (long int) ret_extent
, (long int) extent
[n
]);
520 for (n
= 0; n
< rank
; n
++)
523 dstride
[n
] = GFC_DESCRIPTOR_STRIDE(retarray
,n
);
526 dest
= retarray
->base_addr
;
534 while (count
[n
] == extent
[n
])
536 /* When we get to the end of a dimension, reset it and increment
537 the next dimension. */
539 /* We could precalculate these products, but this is a less
540 frequently used path so probably not worth it. */
541 dest
-= dstride
[n
] * extent
[n
];