Skip gnat.dg/prot7.adb on hppa.
[official-gcc.git] / libgfortran / generated / findloc0_r8.c
blob5a7c239c130f77f4534a3a7f8323fd21a727fb1f
2 /* Implementation of the FINDLOC intrinsic
3 Copyright (C) 2018-2023 Free Software Foundation, Inc.
4 Contributed by Thomas König <tk@tkoenig.net>
6 This file is part of the GNU Fortran 95 runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either
11 version 3 of the License, or (at your option) any later version.
13 Libgfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 #include "libgfortran.h"
28 #include <assert.h>
30 #if defined (HAVE_GFC_REAL_8)
31 extern void findloc0_r8 (gfc_array_index_type * const restrict retarray,
32 gfc_array_r8 * const restrict array, GFC_REAL_8 value,
33 GFC_LOGICAL_4);
34 export_proto(findloc0_r8);
36 void
37 findloc0_r8 (gfc_array_index_type * const restrict retarray,
38 gfc_array_r8 * const restrict array, GFC_REAL_8 value,
39 GFC_LOGICAL_4 back)
41 index_type count[GFC_MAX_DIMENSIONS];
42 index_type extent[GFC_MAX_DIMENSIONS];
43 index_type sstride[GFC_MAX_DIMENSIONS];
44 index_type dstride;
45 const GFC_REAL_8 *base;
46 index_type * restrict dest;
47 index_type rank;
48 index_type n;
49 index_type sz;
51 rank = GFC_DESCRIPTOR_RANK (array);
52 if (rank <= 0)
53 runtime_error ("Rank of array needs to be > 0");
55 if (retarray->base_addr == NULL)
57 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
58 retarray->dtype.rank = 1;
59 retarray->offset = 0;
60 retarray->base_addr = xmallocarray (rank, sizeof (index_type));
62 else
64 if (unlikely (compile_options.bounds_check))
65 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
66 "FINDLOC");
69 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
70 dest = retarray->base_addr;
72 /* Set the return value. */
73 for (n = 0; n < rank; n++)
74 dest[n * dstride] = 0;
76 sz = 1;
77 for (n = 0; n < rank; n++)
79 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
80 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
81 sz *= extent[n];
82 if (extent[n] <= 0)
83 return;
86 for (n = 0; n < rank; n++)
87 count[n] = 0;
89 if (back)
91 base = array->base_addr + (sz - 1) * 1;
93 while (1)
97 if (unlikely(*base == value))
99 for (n = 0; n < rank; n++)
100 dest[n * dstride] = extent[n] - count[n];
102 return;
104 base -= sstride[0] * 1;
105 } while(++count[0] != extent[0]);
107 n = 0;
110 /* When we get to the end of a dimension, reset it and increment
111 the next dimension. */
112 count[n] = 0;
113 /* We could precalculate these products, but this is a less
114 frequently used path so probably not worth it. */
115 base += sstride[n] * extent[n] * 1;
116 n++;
117 if (n >= rank)
118 return;
119 else
121 count[n]++;
122 base -= sstride[n] * 1;
124 } while (count[n] == extent[n]);
127 else
129 base = array->base_addr;
130 while (1)
134 if (unlikely(*base == value))
136 for (n = 0; n < rank; n++)
137 dest[n * dstride] = count[n] + 1;
139 return;
141 base += sstride[0] * 1;
142 } while(++count[0] != extent[0]);
144 n = 0;
147 /* When we get to the end of a dimension, reset it and increment
148 the next dimension. */
149 count[n] = 0;
150 /* We could precalculate these products, but this is a less
151 frequently used path so probably not worth it. */
152 base -= sstride[n] * extent[n] * 1;
153 n++;
154 if (n >= rank)
155 return;
156 else
158 count[n]++;
159 base += sstride[n] * 1;
161 } while (count[n] == extent[n]);
164 return;
167 extern void mfindloc0_r8 (gfc_array_index_type * const restrict retarray,
168 gfc_array_r8 * const restrict array, GFC_REAL_8 value,
169 gfc_array_l1 *const restrict, GFC_LOGICAL_4);
170 export_proto(mfindloc0_r8);
172 void
173 mfindloc0_r8 (gfc_array_index_type * const restrict retarray,
174 gfc_array_r8 * const restrict array, GFC_REAL_8 value,
175 gfc_array_l1 *const restrict mask, GFC_LOGICAL_4 back)
177 index_type count[GFC_MAX_DIMENSIONS];
178 index_type extent[GFC_MAX_DIMENSIONS];
179 index_type sstride[GFC_MAX_DIMENSIONS];
180 index_type mstride[GFC_MAX_DIMENSIONS];
181 index_type dstride;
182 const GFC_REAL_8 *base;
183 index_type * restrict dest;
184 GFC_LOGICAL_1 *mbase;
185 index_type rank;
186 index_type n;
187 int mask_kind;
188 index_type sz;
190 rank = GFC_DESCRIPTOR_RANK (array);
191 if (rank <= 0)
192 runtime_error ("Rank of array needs to be > 0");
194 if (retarray->base_addr == NULL)
196 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
197 retarray->dtype.rank = 1;
198 retarray->offset = 0;
199 retarray->base_addr = xmallocarray (rank, sizeof (index_type));
201 else
203 if (unlikely (compile_options.bounds_check))
205 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
206 "FINDLOC");
207 bounds_equal_extents ((array_t *) mask, (array_t *) array,
208 "MASK argument", "FINDLOC");
212 mask_kind = GFC_DESCRIPTOR_SIZE (mask);
214 mbase = mask->base_addr;
216 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
217 #ifdef HAVE_GFC_LOGICAL_16
218 || mask_kind == 16
219 #endif
221 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
222 else
223 internal_error (NULL, "Funny sized logical array");
225 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
226 dest = retarray->base_addr;
228 /* Set the return value. */
229 for (n = 0; n < rank; n++)
230 dest[n * dstride] = 0;
232 sz = 1;
233 for (n = 0; n < rank; n++)
235 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
236 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
237 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
238 sz *= extent[n];
239 if (extent[n] <= 0)
240 return;
243 for (n = 0; n < rank; n++)
244 count[n] = 0;
246 if (back)
248 base = array->base_addr + (sz - 1) * 1;
249 mbase = mbase + (sz - 1) * mask_kind;
250 while (1)
254 if (unlikely(*mbase && *base == value))
256 for (n = 0; n < rank; n++)
257 dest[n * dstride] = extent[n] - count[n];
259 return;
261 base -= sstride[0] * 1;
262 mbase -= mstride[0];
263 } while(++count[0] != extent[0]);
265 n = 0;
268 /* When we get to the end of a dimension, reset it and increment
269 the next dimension. */
270 count[n] = 0;
271 /* We could precalculate these products, but this is a less
272 frequently used path so probably not worth it. */
273 base += sstride[n] * extent[n] * 1;
274 mbase -= mstride[n] * extent[n];
275 n++;
276 if (n >= rank)
277 return;
278 else
280 count[n]++;
281 base -= sstride[n] * 1;
282 mbase += mstride[n];
284 } while (count[n] == extent[n]);
287 else
289 base = array->base_addr;
290 while (1)
294 if (unlikely(*mbase && *base == value))
296 for (n = 0; n < rank; n++)
297 dest[n * dstride] = count[n] + 1;
299 return;
301 base += sstride[0] * 1;
302 mbase += mstride[0];
303 } while(++count[0] != extent[0]);
305 n = 0;
308 /* When we get to the end of a dimension, reset it and increment
309 the next dimension. */
310 count[n] = 0;
311 /* We could precalculate these products, but this is a less
312 frequently used path so probably not worth it. */
313 base -= sstride[n] * extent[n] * 1;
314 mbase -= mstride[n] * extent[n];
315 n++;
316 if (n >= rank)
317 return;
318 else
320 count[n]++;
321 base += sstride[n]* 1;
322 mbase += mstride[n];
324 } while (count[n] == extent[n]);
327 return;
330 extern void sfindloc0_r8 (gfc_array_index_type * const restrict retarray,
331 gfc_array_r8 * const restrict array, GFC_REAL_8 value,
332 GFC_LOGICAL_4 *, GFC_LOGICAL_4);
333 export_proto(sfindloc0_r8);
335 void
336 sfindloc0_r8 (gfc_array_index_type * const restrict retarray,
337 gfc_array_r8 * const restrict array, GFC_REAL_8 value,
338 GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back)
340 index_type rank;
341 index_type dstride;
342 index_type * restrict dest;
343 index_type n;
345 if (mask == NULL || *mask)
347 findloc0_r8 (retarray, array, value, back);
348 return;
351 rank = GFC_DESCRIPTOR_RANK (array);
353 if (rank <= 0)
354 internal_error (NULL, "Rank of array needs to be > 0");
356 if (retarray->base_addr == NULL)
358 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
359 retarray->dtype.rank = 1;
360 retarray->offset = 0;
361 retarray->base_addr = xmallocarray (rank, sizeof (index_type));
363 else if (unlikely (compile_options.bounds_check))
365 bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
366 "FINDLOC");
369 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
370 dest = retarray->base_addr;
371 for (n = 0; n<rank; n++)
372 dest[n * dstride] = 0 ;
375 #endif