]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/generated/maxloc1_8_r4.c
iresolve.c (gfc_resolve_all, [...]): Use PREFIX.
[thirdparty/gcc.git] / libgfortran / generated / maxloc1_8_r4.c
CommitLineData
6de9cd9a
DN
1/* Implementation of the MAXLOC intrinsic
2 Copyright 2002 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4
5This file is part of the GNU Fortran 95 runtime library (libgfor).
6
7Libgfortran is free software; you can redistribute it and/or
8modify it under the terms of the GNU Lesser General Public
9License as published by the Free Software Foundation; either
10version 2.1 of the License, or (at your option) any later version.
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 Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public
18License along with libgfor; see the file COPYING.LIB. If not,
19write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22#include "config.h"
23#include <stdlib.h>
24#include <assert.h>
25#include <float.h>
26#include <limits.h>
27#include "libgfortran.h"
28
7d7b8bfe 29
7f68c75f
RH
30extern void maxloc1_8_r4 (gfc_array_i8 *, gfc_array_r4 *, index_type *);
31export_proto(maxloc1_8_r4);
7d7b8bfe 32
6de9cd9a 33void
7f68c75f 34maxloc1_8_r4 (gfc_array_i8 *retarray, gfc_array_r4 *array, index_type *pdim)
6de9cd9a
DN
35{
36 index_type count[GFC_MAX_DIMENSIONS - 1];
37 index_type extent[GFC_MAX_DIMENSIONS - 1];
38 index_type sstride[GFC_MAX_DIMENSIONS - 1];
39 index_type dstride[GFC_MAX_DIMENSIONS - 1];
40 GFC_REAL_4 *base;
41 GFC_INTEGER_8 *dest;
42 index_type rank;
43 index_type n;
44 index_type len;
45 index_type delta;
46 index_type dim;
47
48 /* Make dim zero based to avoid confusion. */
49 dim = (*pdim) - 1;
50 rank = GFC_DESCRIPTOR_RANK (array) - 1;
51 assert (rank == GFC_DESCRIPTOR_RANK (retarray));
52 if (array->dim[0].stride == 0)
53 array->dim[0].stride = 1;
54 if (retarray->dim[0].stride == 0)
55 retarray->dim[0].stride = 1;
56
57 len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
58 delta = array->dim[dim].stride;
59
60 for (n = 0; n < dim; n++)
61 {
62 sstride[n] = array->dim[n].stride;
63 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
64 }
65 for (n = dim; n < rank; n++)
66 {
67 sstride[n] = array->dim[n + 1].stride;
68 extent[n] =
69 array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
70 }
71
6c167c45
VL
72 if (retarray->data == NULL)
73 {
74 for (n = 0; n < rank; n++)
75 {
76 retarray->dim[n].lbound = 0;
77 retarray->dim[n].ubound = extent[n]-1;
78 if (n == 0)
79 retarray->dim[n].stride = 1;
80 else
81 retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1];
82 }
83
07d3cebe
RH
84 retarray->data
85 = internal_malloc_size (sizeof (GFC_INTEGER_8)
86 * retarray->dim[rank-1].stride
87 * extent[rank-1]);
6c167c45
VL
88 retarray->base = 0;
89 }
90
6de9cd9a
DN
91 for (n = 0; n < rank; n++)
92 {
93 count[n] = 0;
94 dstride[n] = retarray->dim[n].stride;
95 if (extent[n] <= 0)
96 len = 0;
97 }
98
99 base = array->data;
100 dest = retarray->data;
101
102 while (base)
103 {
104 GFC_REAL_4 *src;
105 GFC_INTEGER_8 result;
106 src = base;
107 {
108
109 GFC_REAL_4 maxval;
110 maxval = -GFC_REAL_4_HUGE;
111 result = 1;
112 if (len <= 0)
113 *dest = 0;
114 else
115 {
116 for (n = 0; n < len; n++, src += delta)
117 {
118
119 if (*src > maxval)
120 {
121 maxval = *src;
122 result = (GFC_INTEGER_8)n + 1;
123 }
124 }
125 *dest = result;
126 }
127 }
128 /* Advance to the next element. */
129 count[0]++;
130 base += sstride[0];
131 dest += dstride[0];
132 n = 0;
133 while (count[n] == extent[n])
134 {
135 /* When we get to the end of a dimension, reset it and increment
136 the next dimension. */
137 count[n] = 0;
138 /* We could precalculate these products, but this is a less
139 frequently used path so proabably not worth it. */
140 base -= sstride[n] * extent[n];
141 dest -= dstride[n] * extent[n];
142 n++;
143 if (n == rank)
144 {
145 /* Break out of the look. */
146 base = NULL;
147 break;
148 }
149 else
150 {
151 count[n]++;
152 base += sstride[n];
153 dest += dstride[n];
154 }
155 }
156 }
157}
158
7d7b8bfe 159
7f68c75f
RH
160extern void mmaxloc1_8_r4 (gfc_array_i8 *, gfc_array_r4 *, index_type *,
161 gfc_array_l4 *);
162export_proto(mmaxloc1_8_r4);
7d7b8bfe 163
6de9cd9a 164void
7f68c75f
RH
165mmaxloc1_8_r4 (gfc_array_i8 * retarray, gfc_array_r4 * array,
166 index_type *pdim, gfc_array_l4 * mask)
6de9cd9a
DN
167{
168 index_type count[GFC_MAX_DIMENSIONS - 1];
169 index_type extent[GFC_MAX_DIMENSIONS - 1];
170 index_type sstride[GFC_MAX_DIMENSIONS - 1];
171 index_type dstride[GFC_MAX_DIMENSIONS - 1];
172 index_type mstride[GFC_MAX_DIMENSIONS - 1];
173 GFC_INTEGER_8 *dest;
174 GFC_REAL_4 *base;
175 GFC_LOGICAL_4 *mbase;
176 int rank;
177 int dim;
178 index_type n;
179 index_type len;
180 index_type delta;
181 index_type mdelta;
182
183 dim = (*pdim) - 1;
184 rank = GFC_DESCRIPTOR_RANK (array) - 1;
185 assert (rank == GFC_DESCRIPTOR_RANK (retarray));
186 if (array->dim[0].stride == 0)
187 array->dim[0].stride = 1;
188 if (retarray->dim[0].stride == 0)
189 retarray->dim[0].stride = 1;
190
191 len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
192 if (len <= 0)
193 return;
194 delta = array->dim[dim].stride;
195 mdelta = mask->dim[dim].stride;
196
197 for (n = 0; n < dim; n++)
198 {
199 sstride[n] = array->dim[n].stride;
200 mstride[n] = mask->dim[n].stride;
201 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
202 }
203 for (n = dim; n < rank; n++)
204 {
205 sstride[n] = array->dim[n + 1].stride;
206 mstride[n] = mask->dim[n + 1].stride;
207 extent[n] =
208 array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
209 }
210
211 for (n = 0; n < rank; n++)
212 {
213 count[n] = 0;
214 dstride[n] = retarray->dim[n].stride;
215 if (extent[n] <= 0)
216 return;
217 }
218
219 dest = retarray->data;
220 base = array->data;
221 mbase = mask->data;
222
223 if (GFC_DESCRIPTOR_SIZE (mask) != 4)
224 {
225 /* This allows the same loop to be used for all logical types. */
226 assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
227 for (n = 0; n < rank; n++)
228 mstride[n] <<= 1;
229 mdelta <<= 1;
230 mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
231 }
232
233 while (base)
234 {
235 GFC_REAL_4 *src;
236 GFC_LOGICAL_4 *msrc;
237 GFC_INTEGER_8 result;
238 src = base;
239 msrc = mbase;
240 {
241
242 GFC_REAL_4 maxval;
243 maxval = -GFC_REAL_4_HUGE;
244 result = 1;
245 if (len <= 0)
246 *dest = 0;
247 else
248 {
249 for (n = 0; n < len; n++, src += delta, msrc += mdelta)
250 {
251
252 if (*msrc && *src > maxval)
253 {
254 maxval = *src;
255 result = (GFC_INTEGER_8)n + 1;
256 }
257 }
258 *dest = result;
259 }
260 }
261 /* Advance to the next element. */
262 count[0]++;
263 base += sstride[0];
264 mbase += mstride[0];
265 dest += dstride[0];
266 n = 0;
267 while (count[n] == extent[n])
268 {
269 /* When we get to the end of a dimension, reset it and increment
270 the next dimension. */
271 count[n] = 0;
272 /* We could precalculate these products, but this is a less
273 frequently used path so proabably not worth it. */
274 base -= sstride[n] * extent[n];
275 mbase -= mstride[n] * extent[n];
276 dest -= dstride[n] * extent[n];
277 n++;
278 if (n == rank)
279 {
280 /* Break out of the look. */
281 base = NULL;
282 break;
283 }
284 else
285 {
286 count[n]++;
287 base += sstride[n];
288 mbase += mstride[n];
289 dest += dstride[n];
290 }
291 }
292 }
293}
294