]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/generated/maxloc0_16_r4.c
[multiple changes]
[thirdparty/gcc.git] / libgfortran / generated / maxloc0_16_r4.c
CommitLineData
644cb69f 1/* Implementation of the MAXLOC intrinsic
748086b7 2 Copyright 2002, 2007, 2009 Free Software Foundation, Inc.
644cb69f
FXC
3 Contributed by Paul Brook <paul@nowt.org>
4
5This file is part of the GNU Fortran 95 runtime library (libgfortran).
6
7Libgfortran is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public
9License as published by the Free Software Foundation; either
748086b7 10version 3 of the License, or (at your option) any later version.
644cb69f
FXC
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
15GNU General Public License for more details.
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/>. */
644cb69f 25
36ae8a61 26#include "libgfortran.h"
644cb69f
FXC
27#include <stdlib.h>
28#include <assert.h>
644cb69f 29#include <limits.h>
644cb69f
FXC
30
31
32#if defined (HAVE_GFC_REAL_4) && defined (HAVE_GFC_INTEGER_16)
33
34
64acfd99
JB
35extern void maxloc0_16_r4 (gfc_array_i16 * const restrict retarray,
36 gfc_array_r4 * const restrict array);
644cb69f
FXC
37export_proto(maxloc0_16_r4);
38
39void
64acfd99
JB
40maxloc0_16_r4 (gfc_array_i16 * const restrict retarray,
41 gfc_array_r4 * const restrict array)
644cb69f
FXC
42{
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;
64acfd99 47 const GFC_REAL_4 *base;
5863aacf 48 GFC_INTEGER_16 * restrict dest;
644cb69f
FXC
49 index_type rank;
50 index_type n;
51
52 rank = GFC_DESCRIPTOR_RANK (array);
53 if (rank <= 0)
54 runtime_error ("Rank of array needs to be > 0");
55
56 if (retarray->data == NULL)
57 {
dfb55fdc 58 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
644cb69f
FXC
59 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1;
60 retarray->offset = 0;
61 retarray->data = internal_malloc_size (sizeof (GFC_INTEGER_16) * rank);
62 }
63 else
64 {
9731c4a3 65 if (unlikely (compile_options.bounds_check))
16bff921
TK
66 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
67 "MAXLOC");
644cb69f
FXC
68 }
69
dfb55fdc 70 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
644cb69f
FXC
71 dest = retarray->data;
72 for (n = 0; n < rank; n++)
73 {
dfb55fdc
TK
74 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
75 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
644cb69f
FXC
76 count[n] = 0;
77 if (extent[n] <= 0)
78 {
79 /* Set the return value. */
80 for (n = 0; n < rank; n++)
81 dest[n * dstride] = 0;
82 return;
83 }
84 }
85
86 base = array->data;
87
88 /* Initialize the return value. */
89 for (n = 0; n < rank; n++)
a4b9e93e 90 dest[n * dstride] = 0;
644cb69f
FXC
91 {
92
93 GFC_REAL_4 maxval;
94
95 maxval = -GFC_REAL_4_HUGE;
96
97 while (base)
98 {
99 {
100 /* Implementation start. */
101
a4b9e93e 102 if (*base > maxval || !dest[0])
644cb69f
FXC
103 {
104 maxval = *base;
105 for (n = 0; n < rank; n++)
106 dest[n * dstride] = count[n] + 1;
107 }
108 /* Implementation end. */
109 }
110 /* Advance to the next element. */
111 count[0]++;
112 base += sstride[0];
113 n = 0;
114 while (count[n] == extent[n])
115 {
116 /* When we get to the end of a dimension, reset it and increment
117 the next dimension. */
118 count[n] = 0;
119 /* We could precalculate these products, but this is a less
5d7adf7a 120 frequently used path so probably not worth it. */
644cb69f
FXC
121 base -= sstride[n] * extent[n];
122 n++;
123 if (n == rank)
124 {
125 /* Break out of the loop. */
126 base = NULL;
127 break;
128 }
129 else
130 {
131 count[n]++;
132 base += sstride[n];
133 }
134 }
135 }
136 }
137}
138
139
64acfd99 140extern void mmaxloc0_16_r4 (gfc_array_i16 * const restrict,
28dc6b33 141 gfc_array_r4 * const restrict, gfc_array_l1 * const restrict);
644cb69f
FXC
142export_proto(mmaxloc0_16_r4);
143
144void
64acfd99
JB
145mmaxloc0_16_r4 (gfc_array_i16 * const restrict retarray,
146 gfc_array_r4 * const restrict array,
28dc6b33 147 gfc_array_l1 * const restrict mask)
644cb69f
FXC
148{
149 index_type count[GFC_MAX_DIMENSIONS];
150 index_type extent[GFC_MAX_DIMENSIONS];
151 index_type sstride[GFC_MAX_DIMENSIONS];
152 index_type mstride[GFC_MAX_DIMENSIONS];
153 index_type dstride;
154 GFC_INTEGER_16 *dest;
64acfd99 155 const GFC_REAL_4 *base;
28dc6b33 156 GFC_LOGICAL_1 *mbase;
644cb69f
FXC
157 int rank;
158 index_type n;
28dc6b33 159 int mask_kind;
644cb69f
FXC
160
161 rank = GFC_DESCRIPTOR_RANK (array);
162 if (rank <= 0)
163 runtime_error ("Rank of array needs to be > 0");
164
165 if (retarray->data == NULL)
166 {
dfb55fdc 167 GFC_DIMENSION_SET(retarray->dim[0], 0, rank - 1, 1);
644cb69f
FXC
168 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1;
169 retarray->offset = 0;
170 retarray->data = internal_malloc_size (sizeof (GFC_INTEGER_16) * rank);
171 }
172 else
173 {
9731c4a3 174 if (unlikely (compile_options.bounds_check))
fd6590f8 175 {
16bff921
TK
176
177 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
178 "MAXLOC");
179 bounds_equal_extents ((array_t *) mask, (array_t *) array,
180 "MASK argument", "MAXLOC");
fd6590f8 181 }
644cb69f
FXC
182 }
183
28dc6b33
TK
184 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
185
186 mbase = mask->data;
187
188 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
189#ifdef HAVE_GFC_LOGICAL_16
190 || mask_kind == 16
191#endif
192 )
193 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
194 else
195 runtime_error ("Funny sized logical array");
196
dfb55fdc 197 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
644cb69f
FXC
198 dest = retarray->data;
199 for (n = 0; n < rank; n++)
200 {
dfb55fdc
TK
201 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
202 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
203 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
644cb69f
FXC
204 count[n] = 0;
205 if (extent[n] <= 0)
206 {
207 /* Set the return value. */
208 for (n = 0; n < rank; n++)
209 dest[n * dstride] = 0;
210 return;
211 }
212 }
213
214 base = array->data;
644cb69f
FXC
215
216 /* Initialize the return value. */
217 for (n = 0; n < rank; n++)
a4b9e93e 218 dest[n * dstride] = 0;
644cb69f
FXC
219 {
220
221 GFC_REAL_4 maxval;
222
223 maxval = -GFC_REAL_4_HUGE;
224
225 while (base)
226 {
227 {
228 /* Implementation start. */
229
a4b9e93e 230 if (*mbase && (*base > maxval || !dest[0]))
644cb69f
FXC
231 {
232 maxval = *base;
233 for (n = 0; n < rank; n++)
234 dest[n * dstride] = count[n] + 1;
235 }
236 /* Implementation end. */
237 }
238 /* Advance to the next element. */
239 count[0]++;
240 base += sstride[0];
241 mbase += mstride[0];
242 n = 0;
243 while (count[n] == extent[n])
244 {
245 /* When we get to the end of a dimension, reset it and increment
246 the next dimension. */
247 count[n] = 0;
248 /* We could precalculate these products, but this is a less
5d7adf7a 249 frequently used path so probably not worth it. */
644cb69f
FXC
250 base -= sstride[n] * extent[n];
251 mbase -= mstride[n] * extent[n];
252 n++;
253 if (n == rank)
254 {
255 /* Break out of the loop. */
256 base = NULL;
257 break;
258 }
259 else
260 {
261 count[n]++;
262 base += sstride[n];
263 mbase += mstride[n];
264 }
265 }
266 }
267 }
268}
269
97a62038
TK
270
271extern void smaxloc0_16_r4 (gfc_array_i16 * const restrict,
272 gfc_array_r4 * const restrict, GFC_LOGICAL_4 *);
273export_proto(smaxloc0_16_r4);
274
275void
276smaxloc0_16_r4 (gfc_array_i16 * const restrict retarray,
277 gfc_array_r4 * const restrict array,
278 GFC_LOGICAL_4 * mask)
279{
280 index_type rank;
281 index_type dstride;
282 index_type n;
283 GFC_INTEGER_16 *dest;
284
285 if (*mask)
286 {
287 maxloc0_16_r4 (retarray, array);
288 return;
289 }
290
291 rank = GFC_DESCRIPTOR_RANK (array);
292
293 if (rank <= 0)
294 runtime_error ("Rank of array needs to be > 0");
295
296 if (retarray->data == NULL)
297 {
dfb55fdc 298 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
97a62038
TK
299 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1;
300 retarray->offset = 0;
301 retarray->data = internal_malloc_size (sizeof (GFC_INTEGER_16) * rank);
302 }
16bff921 303 else if (unlikely (compile_options.bounds_check))
97a62038 304 {
16bff921
TK
305 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
306 "MAXLOC");
97a62038
TK
307 }
308
dfb55fdc 309 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
97a62038
TK
310 dest = retarray->data;
311 for (n = 0; n<rank; n++)
312 dest[n * dstride] = 0 ;
313}
644cb69f 314#endif