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