| OLD | NEW |
| 1 /* Implementation of the MAXLOC intrinsic | 1 /* Implementation of the MAXLOC intrinsic |
| 2 Copyright 2002, 2007, 2009 Free Software Foundation, Inc. | 2 Copyright 2002, 2007, 2009 Free Software Foundation, Inc. |
| 3 Contributed by Paul Brook <paul@nowt.org> | 3 Contributed by Paul Brook <paul@nowt.org> |
| 4 | 4 |
| 5 This file is part of the GNU Fortran 95 runtime library (libgfortran). | 5 This file is part of the GNU Fortran 95 runtime library (libgfortran). |
| 6 | 6 |
| 7 Libgfortran is free software; you can redistribute it and/or | 7 Libgfortran is free software; you can redistribute it and/or |
| 8 modify it under the terms of the GNU General Public | 8 modify it under the terms of the GNU General Public |
| 9 License as published by the Free Software Foundation; either | 9 License as published by the Free Software Foundation; either |
| 10 version 3 of the License, or (at your option) any later version. | 10 version 3 of the License, or (at your option) any later version. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 GFC_INTEGER_4 * restrict dest; | 48 GFC_INTEGER_4 * restrict dest; |
| 49 index_type rank; | 49 index_type rank; |
| 50 index_type n; | 50 index_type n; |
| 51 | 51 |
| 52 rank = GFC_DESCRIPTOR_RANK (array); | 52 rank = GFC_DESCRIPTOR_RANK (array); |
| 53 if (rank <= 0) | 53 if (rank <= 0) |
| 54 runtime_error ("Rank of array needs to be > 0"); | 54 runtime_error ("Rank of array needs to be > 0"); |
| 55 | 55 |
| 56 if (retarray->data == NULL) | 56 if (retarray->data == NULL) |
| 57 { | 57 { |
| 58 retarray->dim[0].lbound = 0; | 58 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1); |
| 59 retarray->dim[0].ubound = rank-1; | |
| 60 retarray->dim[0].stride = 1; | |
| 61 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1; | 59 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1; |
| 62 retarray->offset = 0; | 60 retarray->offset = 0; |
| 63 retarray->data = internal_malloc_size (sizeof (GFC_INTEGER_4) * rank); | 61 retarray->data = internal_malloc_size (sizeof (GFC_INTEGER_4) * rank); |
| 64 } | 62 } |
| 65 else | 63 else |
| 66 { | 64 { |
| 67 if (unlikely (compile_options.bounds_check)) | 65 if (unlikely (compile_options.bounds_check)) |
| 68 » { | 66 » bounds_iforeach_return ((array_t *) retarray, (array_t *) array, |
| 69 » int ret_rank; | 67 » » » » "MAXLOC"); |
| 70 » index_type ret_extent; | |
| 71 | |
| 72 » ret_rank = GFC_DESCRIPTOR_RANK (retarray); | |
| 73 » if (ret_rank != 1) | |
| 74 » runtime_error ("rank of return array in MAXLOC intrinsic" | |
| 75 » » » " should be 1, is %ld", (long int) ret_rank); | |
| 76 | |
| 77 » ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; | |
| 78 » if (ret_extent != rank) | |
| 79 » runtime_error ("Incorrect extent in return value of" | |
| 80 » » » " MAXLOC intrnisic: is %ld, should be %ld", | |
| 81 » » » (long int) ret_extent, (long int) rank); | |
| 82 » } | |
| 83 } | 68 } |
| 84 | 69 |
| 85 dstride = retarray->dim[0].stride; | 70 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0); |
| 86 dest = retarray->data; | 71 dest = retarray->data; |
| 87 for (n = 0; n < rank; n++) | 72 for (n = 0; n < rank; n++) |
| 88 { | 73 { |
| 89 sstride[n] = array->dim[n].stride; | 74 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); |
| 90 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound; | 75 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); |
| 91 count[n] = 0; | 76 count[n] = 0; |
| 92 if (extent[n] <= 0) | 77 if (extent[n] <= 0) |
| 93 { | 78 { |
| 94 /* Set the return value. */ | 79 /* Set the return value. */ |
| 95 for (n = 0; n < rank; n++) | 80 for (n = 0; n < rank; n++) |
| 96 dest[n * dstride] = 0; | 81 dest[n * dstride] = 0; |
| 97 return; | 82 return; |
| 98 } | 83 } |
| 99 } | 84 } |
| 100 | 85 |
| 101 base = array->data; | 86 base = array->data; |
| 102 | 87 |
| 103 /* Initialize the return value. */ | 88 /* Initialize the return value. */ |
| 104 for (n = 0; n < rank; n++) | 89 for (n = 0; n < rank; n++) |
| 105 dest[n * dstride] = 0; | 90 dest[n * dstride] = 1; |
| 106 { | 91 { |
| 107 | 92 |
| 108 GFC_INTEGER_2 maxval; | 93 GFC_INTEGER_2 maxval; |
| 94 #if defined(GFC_INTEGER_2_QUIET_NAN) |
| 95 int fast = 0; |
| 96 #endif |
| 109 | 97 |
| 110 maxval = (-GFC_INTEGER_2_HUGE-1); | 98 #if defined(GFC_INTEGER_2_INFINITY) |
| 111 | 99 maxval = -GFC_INTEGER_2_INFINITY; |
| 100 #else |
| 101 maxval = (-GFC_INTEGER_2_HUGE-1); |
| 102 #endif |
| 112 while (base) | 103 while (base) |
| 113 { | 104 { |
| 114 { | 105 do |
| 115 /* Implementation start. */ | 106 » { |
| 107 » /* Implementation start. */ |
| 116 | 108 |
| 117 if (*base > maxval || !dest[0]) | 109 #if defined(GFC_INTEGER_2_QUIET_NAN) |
| 118 { | 110 » } |
| 119 maxval = *base; | 111 while (0); |
| 120 for (n = 0; n < rank; n++) | 112 if (unlikely (!fast)) |
| 121 dest[n * dstride] = count[n] + 1; | 113 » { |
| 122 } | 114 » do |
| 123 /* Implementation end. */ | 115 » { |
| 124 } | 116 » if (*base >= maxval) |
| 125 /* Advance to the next element. */ | 117 » » { |
| 126 count[0]++; | 118 » » fast = 1; |
| 127 base += sstride[0]; | 119 » » maxval = *base; |
| 120 » » for (n = 0; n < rank; n++) |
| 121 » » dest[n * dstride] = count[n] + 1; |
| 122 » » break; |
| 123 » » } |
| 124 » base += sstride[0]; |
| 125 » } |
| 126 » while (++count[0] != extent[0]); |
| 127 » if (likely (fast)) |
| 128 » continue; |
| 129 » } |
| 130 else do |
| 131 » { |
| 132 #endif |
| 133 » if (*base > maxval) |
| 134 » { |
| 135 » maxval = *base; |
| 136 » for (n = 0; n < rank; n++) |
| 137 » » dest[n * dstride] = count[n] + 1; |
| 138 » } |
| 139 » /* Implementation end. */ |
| 140 » /* Advance to the next element. */ |
| 141 » base += sstride[0]; |
| 142 » } |
| 143 while (++count[0] != extent[0]); |
| 128 n = 0; | 144 n = 0; |
| 129 while (count[n] == extent[n]) | 145 do |
| 130 { | 146 » { |
| 131 /* When we get to the end of a dimension, reset it and increment | 147 » /* When we get to the end of a dimension, reset it and increment |
| 132 the next dimension. */ | 148 » the next dimension. */ |
| 133 count[n] = 0; | 149 » count[n] = 0; |
| 134 /* We could precalculate these products, but this is a less | 150 » /* We could precalculate these products, but this is a less |
| 135 frequently used path so probably not worth it. */ | 151 » frequently used path so probably not worth it. */ |
| 136 base -= sstride[n] * extent[n]; | 152 » base -= sstride[n] * extent[n]; |
| 137 n++; | 153 » n++; |
| 138 if (n == rank) | 154 » if (n == rank) |
| 139 { | 155 » { |
| 140 /* Break out of the loop. */ | 156 » /* Break out of the loop. */ |
| 141 base = NULL; | 157 » base = NULL; |
| 142 break; | 158 » break; |
| 143 } | 159 » } |
| 144 else | 160 » else |
| 145 { | 161 » { |
| 146 count[n]++; | 162 » count[n]++; |
| 147 base += sstride[n]; | 163 » base += sstride[n]; |
| 148 } | 164 » } |
| 149 } | 165 » } |
| 166 while (count[n] == extent[n]); |
| 150 } | 167 } |
| 151 } | 168 } |
| 152 } | 169 } |
| 153 | 170 |
| 154 | 171 |
| 155 extern void mmaxloc0_4_i2 (gfc_array_i4 * const restrict, | 172 extern void mmaxloc0_4_i2 (gfc_array_i4 * const restrict, |
| 156 gfc_array_i2 * const restrict, gfc_array_l1 * const restrict); | 173 gfc_array_i2 * const restrict, gfc_array_l1 * const restrict); |
| 157 export_proto(mmaxloc0_4_i2); | 174 export_proto(mmaxloc0_4_i2); |
| 158 | 175 |
| 159 void | 176 void |
| (...skipping 12 matching lines...) Expand all Loading... |
| 172 int rank; | 189 int rank; |
| 173 index_type n; | 190 index_type n; |
| 174 int mask_kind; | 191 int mask_kind; |
| 175 | 192 |
| 176 rank = GFC_DESCRIPTOR_RANK (array); | 193 rank = GFC_DESCRIPTOR_RANK (array); |
| 177 if (rank <= 0) | 194 if (rank <= 0) |
| 178 runtime_error ("Rank of array needs to be > 0"); | 195 runtime_error ("Rank of array needs to be > 0"); |
| 179 | 196 |
| 180 if (retarray->data == NULL) | 197 if (retarray->data == NULL) |
| 181 { | 198 { |
| 182 retarray->dim[0].lbound = 0; | 199 GFC_DIMENSION_SET(retarray->dim[0], 0, rank - 1, 1); |
| 183 retarray->dim[0].ubound = rank-1; | |
| 184 retarray->dim[0].stride = 1; | |
| 185 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1; | 200 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1; |
| 186 retarray->offset = 0; | 201 retarray->offset = 0; |
| 187 retarray->data = internal_malloc_size (sizeof (GFC_INTEGER_4) * rank); | 202 retarray->data = internal_malloc_size (sizeof (GFC_INTEGER_4) * rank); |
| 188 } | 203 } |
| 189 else | 204 else |
| 190 { | 205 { |
| 191 if (unlikely (compile_options.bounds_check)) | 206 if (unlikely (compile_options.bounds_check)) |
| 192 { | 207 { |
| 193 int ret_rank, mask_rank; | |
| 194 index_type ret_extent; | |
| 195 int n; | |
| 196 index_type array_extent, mask_extent; | |
| 197 | 208 |
| 198 » ret_rank = GFC_DESCRIPTOR_RANK (retarray); | 209 » bounds_iforeach_return ((array_t *) retarray, (array_t *) array, |
| 199 » if (ret_rank != 1) | 210 » » » » "MAXLOC"); |
| 200 » runtime_error ("rank of return array in MAXLOC intrinsic" | 211 » bounds_equal_extents ((array_t *) mask, (array_t *) array, |
| 201 » » » " should be 1, is %ld", (long int) ret_rank); | 212 » » » » "MASK argument", "MAXLOC"); |
| 202 | |
| 203 » ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; | |
| 204 » if (ret_extent != rank) | |
| 205 » runtime_error ("Incorrect extent in return value of" | |
| 206 » » » " MAXLOC intrnisic: is %ld, should be %ld", | |
| 207 » » » (long int) ret_extent, (long int) rank); | |
| 208 » | |
| 209 » mask_rank = GFC_DESCRIPTOR_RANK (mask); | |
| 210 » if (rank != mask_rank) | |
| 211 » runtime_error ("rank of MASK argument in MAXLOC intrnisic" | |
| 212 » "should be %ld, is %ld", (long int) rank, | |
| 213 » » » (long int) mask_rank); | |
| 214 | |
| 215 » for (n=0; n<rank; n++) | |
| 216 » { | |
| 217 » array_extent = array->dim[n].ubound + 1 - array->dim[n].lbound; | |
| 218 » mask_extent = mask->dim[n].ubound + 1 - mask->dim[n].lbound; | |
| 219 » if (array_extent != mask_extent) | |
| 220 » » runtime_error ("Incorrect extent in MASK argument of" | |
| 221 » » » " MAXLOC intrinsic in dimension %ld:" | |
| 222 » » » " is %ld, should be %ld", (long int) n + 1, | |
| 223 » » » (long int) mask_extent, (long int) array_extent); | |
| 224 » } | |
| 225 } | 213 } |
| 226 } | 214 } |
| 227 | 215 |
| 228 mask_kind = GFC_DESCRIPTOR_SIZE (mask); | 216 mask_kind = GFC_DESCRIPTOR_SIZE (mask); |
| 229 | 217 |
| 230 mbase = mask->data; | 218 mbase = mask->data; |
| 231 | 219 |
| 232 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8 | 220 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8 |
| 233 #ifdef HAVE_GFC_LOGICAL_16 | 221 #ifdef HAVE_GFC_LOGICAL_16 |
| 234 || mask_kind == 16 | 222 || mask_kind == 16 |
| 235 #endif | 223 #endif |
| 236 ) | 224 ) |
| 237 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind); | 225 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind); |
| 238 else | 226 else |
| 239 runtime_error ("Funny sized logical array"); | 227 runtime_error ("Funny sized logical array"); |
| 240 | 228 |
| 241 dstride = retarray->dim[0].stride; | 229 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0); |
| 242 dest = retarray->data; | 230 dest = retarray->data; |
| 243 for (n = 0; n < rank; n++) | 231 for (n = 0; n < rank; n++) |
| 244 { | 232 { |
| 245 sstride[n] = array->dim[n].stride; | 233 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); |
| 246 mstride[n] = mask->dim[n].stride * mask_kind; | 234 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n); |
| 247 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound; | 235 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); |
| 248 count[n] = 0; | 236 count[n] = 0; |
| 249 if (extent[n] <= 0) | 237 if (extent[n] <= 0) |
| 250 { | 238 { |
| 251 /* Set the return value. */ | 239 /* Set the return value. */ |
| 252 for (n = 0; n < rank; n++) | 240 for (n = 0; n < rank; n++) |
| 253 dest[n * dstride] = 0; | 241 dest[n * dstride] = 0; |
| 254 return; | 242 return; |
| 255 } | 243 } |
| 256 } | 244 } |
| 257 | 245 |
| 258 base = array->data; | 246 base = array->data; |
| 259 | 247 |
| 260 /* Initialize the return value. */ | 248 /* Initialize the return value. */ |
| 261 for (n = 0; n < rank; n++) | 249 for (n = 0; n < rank; n++) |
| 262 dest[n * dstride] = 0; | 250 dest[n * dstride] = 0; |
| 263 { | 251 { |
| 264 | 252 |
| 265 GFC_INTEGER_2 maxval; | 253 GFC_INTEGER_2 maxval; |
| 254 int fast = 0; |
| 266 | 255 |
| 267 maxval = (-GFC_INTEGER_2_HUGE-1); | 256 #if defined(GFC_INTEGER_2_INFINITY) |
| 268 | 257 maxval = -GFC_INTEGER_2_INFINITY; |
| 258 #else |
| 259 maxval = (-GFC_INTEGER_2_HUGE-1); |
| 260 #endif |
| 269 while (base) | 261 while (base) |
| 270 { | 262 { |
| 271 { | 263 do |
| 272 /* Implementation start. */ | 264 » { |
| 265 » /* Implementation start. */ |
| 273 | 266 |
| 274 if (*mbase && (*base > maxval || !dest[0])) | 267 » } |
| 275 { | 268 while (0); |
| 276 maxval = *base; | 269 if (unlikely (!fast)) |
| 277 for (n = 0; n < rank; n++) | 270 » { |
| 278 dest[n * dstride] = count[n] + 1; | 271 » do |
| 279 } | 272 » { |
| 280 /* Implementation end. */ | 273 » if (*mbase) |
| 281 } | 274 » » { |
| 282 /* Advance to the next element. */ | 275 #if defined(GFC_INTEGER_2_QUIET_NAN) |
| 283 count[0]++; | 276 » » if (unlikely (dest[0] == 0)) |
| 284 base += sstride[0]; | 277 » » for (n = 0; n < rank; n++) |
| 285 mbase += mstride[0]; | 278 » » dest[n * dstride] = count[n] + 1; |
| 279 » » if (*base >= maxval) |
| 280 #endif |
| 281 » » { |
| 282 » » fast = 1; |
| 283 » » maxval = *base; |
| 284 » » for (n = 0; n < rank; n++) |
| 285 » » » dest[n * dstride] = count[n] + 1; |
| 286 » » break; |
| 287 » » } |
| 288 » » } |
| 289 » base += sstride[0]; |
| 290 » mbase += mstride[0]; |
| 291 » } |
| 292 » while (++count[0] != extent[0]); |
| 293 » if (likely (fast)) |
| 294 » continue; |
| 295 » } |
| 296 else do |
| 297 » { |
| 298 » if (*mbase && *base > maxval) |
| 299 » { |
| 300 » maxval = *base; |
| 301 » for (n = 0; n < rank; n++) |
| 302 » » dest[n * dstride] = count[n] + 1; |
| 303 » } |
| 304 » /* Implementation end. */ |
| 305 » /* Advance to the next element. */ |
| 306 » base += sstride[0]; |
| 307 » mbase += mstride[0]; |
| 308 » } |
| 309 while (++count[0] != extent[0]); |
| 286 n = 0; | 310 n = 0; |
| 287 while (count[n] == extent[n]) | 311 do |
| 288 { | 312 » { |
| 289 /* When we get to the end of a dimension, reset it and increment | 313 » /* When we get to the end of a dimension, reset it and increment |
| 290 the next dimension. */ | 314 » the next dimension. */ |
| 291 count[n] = 0; | 315 » count[n] = 0; |
| 292 /* We could precalculate these products, but this is a less | 316 » /* We could precalculate these products, but this is a less |
| 293 frequently used path so probably not worth it. */ | 317 » frequently used path so probably not worth it. */ |
| 294 base -= sstride[n] * extent[n]; | 318 » base -= sstride[n] * extent[n]; |
| 295 mbase -= mstride[n] * extent[n]; | 319 » mbase -= mstride[n] * extent[n]; |
| 296 n++; | 320 » n++; |
| 297 if (n == rank) | 321 » if (n == rank) |
| 298 { | 322 » { |
| 299 /* Break out of the loop. */ | 323 » /* Break out of the loop. */ |
| 300 base = NULL; | 324 » base = NULL; |
| 301 break; | 325 » break; |
| 302 } | 326 » } |
| 303 else | 327 » else |
| 304 { | 328 » { |
| 305 count[n]++; | 329 » count[n]++; |
| 306 base += sstride[n]; | 330 » base += sstride[n]; |
| 307 mbase += mstride[n]; | 331 » mbase += mstride[n]; |
| 308 } | 332 » } |
| 309 } | 333 » } |
| 334 while (count[n] == extent[n]); |
| 310 } | 335 } |
| 311 } | 336 } |
| 312 } | 337 } |
| 313 | 338 |
| 314 | 339 |
| 315 extern void smaxloc0_4_i2 (gfc_array_i4 * const restrict, | 340 extern void smaxloc0_4_i2 (gfc_array_i4 * const restrict, |
| 316 gfc_array_i2 * const restrict, GFC_LOGICAL_4 *); | 341 gfc_array_i2 * const restrict, GFC_LOGICAL_4 *); |
| 317 export_proto(smaxloc0_4_i2); | 342 export_proto(smaxloc0_4_i2); |
| 318 | 343 |
| 319 void | 344 void |
| (...skipping 12 matching lines...) Expand all Loading... |
| 332 return; | 357 return; |
| 333 } | 358 } |
| 334 | 359 |
| 335 rank = GFC_DESCRIPTOR_RANK (array); | 360 rank = GFC_DESCRIPTOR_RANK (array); |
| 336 | 361 |
| 337 if (rank <= 0) | 362 if (rank <= 0) |
| 338 runtime_error ("Rank of array needs to be > 0"); | 363 runtime_error ("Rank of array needs to be > 0"); |
| 339 | 364 |
| 340 if (retarray->data == NULL) | 365 if (retarray->data == NULL) |
| 341 { | 366 { |
| 342 retarray->dim[0].lbound = 0; | 367 GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1); |
| 343 retarray->dim[0].ubound = rank-1; | |
| 344 retarray->dim[0].stride = 1; | |
| 345 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1; | 368 retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1; |
| 346 retarray->offset = 0; | 369 retarray->offset = 0; |
| 347 retarray->data = internal_malloc_size (sizeof (GFC_INTEGER_4) * rank); | 370 retarray->data = internal_malloc_size (sizeof (GFC_INTEGER_4) * rank); |
| 348 } | 371 } |
| 349 else | 372 else if (unlikely (compile_options.bounds_check)) |
| 350 { | 373 { |
| 351 if (unlikely (compile_options.bounds_check)) | 374 bounds_iforeach_return ((array_t *) retarray, (array_t *) array, |
| 352 » { | 375 » » » "MAXLOC"); |
| 353 » int ret_rank; | |
| 354 » index_type ret_extent; | |
| 355 | |
| 356 » ret_rank = GFC_DESCRIPTOR_RANK (retarray); | |
| 357 » if (ret_rank != 1) | |
| 358 » runtime_error ("rank of return array in MAXLOC intrinsic" | |
| 359 » » » " should be 1, is %ld", (long int) ret_rank); | |
| 360 | |
| 361 » ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; | |
| 362 » if (ret_extent != rank) | |
| 363 » runtime_error ("dimension of return array incorrect"); | |
| 364 » } | |
| 365 } | 376 } |
| 366 | 377 |
| 367 dstride = retarray->dim[0].stride; | 378 dstride = GFC_DESCRIPTOR_STRIDE(retarray,0); |
| 368 dest = retarray->data; | 379 dest = retarray->data; |
| 369 for (n = 0; n<rank; n++) | 380 for (n = 0; n<rank; n++) |
| 370 dest[n * dstride] = 0 ; | 381 dest[n * dstride] = 0 ; |
| 371 } | 382 } |
| 372 #endif | 383 #endif |
| OLD | NEW |