| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 index_type n; | 51 index_type n; |
| 52 index_type len; | 52 index_type len; |
| 53 index_type delta; | 53 index_type delta; |
| 54 index_type dim; | 54 index_type dim; |
| 55 int continue_loop; | 55 int continue_loop; |
| 56 | 56 |
| 57 /* Make dim zero based to avoid confusion. */ | 57 /* Make dim zero based to avoid confusion. */ |
| 58 dim = (*pdim) - 1; | 58 dim = (*pdim) - 1; |
| 59 rank = GFC_DESCRIPTOR_RANK (array) - 1; | 59 rank = GFC_DESCRIPTOR_RANK (array) - 1; |
| 60 | 60 |
| 61 len = array->dim[dim].ubound + 1 - array->dim[dim].lbound; | 61 len = GFC_DESCRIPTOR_EXTENT(array,dim); |
| 62 if (len < 0) | 62 if (len < 0) |
| 63 len = 0; | 63 len = 0; |
| 64 delta = array->dim[dim].stride; | 64 delta = GFC_DESCRIPTOR_STRIDE(array,dim); |
| 65 | 65 |
| 66 for (n = 0; n < dim; n++) | 66 for (n = 0; n < dim; n++) |
| 67 { | 67 { |
| 68 sstride[n] = array->dim[n].stride; | 68 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); |
| 69 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound; | 69 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); |
| 70 | 70 |
| 71 if (extent[n] < 0) | 71 if (extent[n] < 0) |
| 72 extent[n] = 0; | 72 extent[n] = 0; |
| 73 } | 73 } |
| 74 for (n = dim; n < rank; n++) | 74 for (n = dim; n < rank; n++) |
| 75 { | 75 { |
| 76 sstride[n] = array->dim[n + 1].stride; | 76 sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1); |
| 77 extent[n] = | 77 extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1); |
| 78 array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound; | |
| 79 | 78 |
| 80 if (extent[n] < 0) | 79 if (extent[n] < 0) |
| 81 extent[n] = 0; | 80 extent[n] = 0; |
| 82 } | 81 } |
| 83 | 82 |
| 84 if (retarray->data == NULL) | 83 if (retarray->data == NULL) |
| 85 { | 84 { |
| 86 size_t alloc_size; | 85 size_t alloc_size, str; |
| 87 | 86 |
| 88 for (n = 0; n < rank; n++) | 87 for (n = 0; n < rank; n++) |
| 89 { | 88 » { |
| 90 retarray->dim[n].lbound = 0; | 89 » if (n == 0) |
| 91 retarray->dim[n].ubound = extent[n]-1; | 90 » str = 1; |
| 92 if (n == 0) | 91 » else |
| 93 retarray->dim[n].stride = 1; | 92 » str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1]; |
| 94 else | 93 |
| 95 retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1]; | 94 » GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str); |
| 96 } | 95 |
| 96 » } |
| 97 | 97 |
| 98 retarray->offset = 0; | 98 retarray->offset = 0; |
| 99 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank; | 99 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank; |
| 100 | 100 |
| 101 alloc_size = sizeof (GFC_INTEGER_4) * retarray->dim[rank-1].stride | 101 alloc_size = sizeof (GFC_INTEGER_4) * GFC_DESCRIPTOR_STRIDE(retarray,rank-
1) |
| 102 * extent[rank-1]; | 102 * extent[rank-1]; |
| 103 | 103 |
| 104 if (alloc_size == 0) | 104 if (alloc_size == 0) |
| 105 { | 105 { |
| 106 /* Make sure we have a zero-sized array. */ | 106 /* Make sure we have a zero-sized array. */ |
| 107 » retarray->dim[0].lbound = 0; | 107 » GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); |
| 108 » retarray->dim[0].ubound = -1; | |
| 109 return; | 108 return; |
| 109 |
| 110 } | 110 } |
| 111 else | 111 else |
| 112 retarray->data = internal_malloc_size (alloc_size); | 112 retarray->data = internal_malloc_size (alloc_size); |
| 113 } | 113 } |
| 114 else | 114 else |
| 115 { | 115 { |
| 116 if (rank != GFC_DESCRIPTOR_RANK (retarray)) | 116 if (rank != GFC_DESCRIPTOR_RANK (retarray)) |
| 117 runtime_error ("rank of return array incorrect in" | 117 runtime_error ("rank of return array incorrect in" |
| 118 " MAXLOC intrinsic: is %ld, should be %ld", | 118 " MAXLOC intrinsic: is %ld, should be %ld", |
| 119 (long int) (GFC_DESCRIPTOR_RANK (retarray)), | 119 (long int) (GFC_DESCRIPTOR_RANK (retarray)), |
| 120 (long int) rank); | 120 (long int) rank); |
| 121 | 121 |
| 122 if (unlikely (compile_options.bounds_check)) | 122 if (unlikely (compile_options.bounds_check)) |
| 123 » { | 123 » bounds_ifunction_return ((array_t *) retarray, extent, |
| 124 » for (n=0; n < rank; n++) | 124 » » » » "return value", "MAXLOC"); |
| 125 » { | |
| 126 » index_type ret_extent; | |
| 127 | |
| 128 » ret_extent = retarray->dim[n].ubound + 1 | |
| 129 » » - retarray->dim[n].lbound; | |
| 130 » if (extent[n] != ret_extent) | |
| 131 » » runtime_error ("Incorrect extent in return value of" | |
| 132 » » » " MAXLOC intrinsic in dimension %ld:" | |
| 133 » » » " is %ld, should be %ld", (long int) n + 1, | |
| 134 » » » (long int) ret_extent, (long int) extent[n]); | |
| 135 » } | |
| 136 » } | |
| 137 } | 125 } |
| 138 | 126 |
| 139 for (n = 0; n < rank; n++) | 127 for (n = 0; n < rank; n++) |
| 140 { | 128 { |
| 141 count[n] = 0; | 129 count[n] = 0; |
| 142 dstride[n] = retarray->dim[n].stride; | 130 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n); |
| 143 if (extent[n] <= 0) | 131 if (extent[n] <= 0) |
| 144 len = 0; | 132 » len = 0; |
| 145 } | 133 } |
| 146 | 134 |
| 147 base = array->data; | 135 base = array->data; |
| 148 dest = retarray->data; | 136 dest = retarray->data; |
| 149 | 137 |
| 150 continue_loop = 1; | 138 continue_loop = 1; |
| 151 while (continue_loop) | 139 while (continue_loop) |
| 152 { | 140 { |
| 153 const GFC_REAL_8 * restrict src; | 141 const GFC_REAL_8 * restrict src; |
| 154 GFC_INTEGER_4 result; | 142 GFC_INTEGER_4 result; |
| 155 src = base; | 143 src = base; |
| 156 { | 144 { |
| 157 | 145 |
| 158 GFC_REAL_8 maxval; | 146 » GFC_REAL_8 maxval; |
| 159 maxval = -GFC_REAL_8_HUGE; | 147 #if defined (GFC_REAL_8_INFINITY) |
| 160 result = 0; | 148 » maxval = -GFC_REAL_8_INFINITY; |
| 161 if (len <= 0) | 149 #else |
| 150 » maxval = -GFC_REAL_8_HUGE; |
| 151 #endif |
| 152 » result = 1; |
| 153 » if (len <= 0) |
| 162 *dest = 0; | 154 *dest = 0; |
| 163 else | 155 else |
| 164 { | 156 { |
| 165 for (n = 0; n < len; n++, src += delta) | 157 for (n = 0; n < len; n++, src += delta) |
| 166 { | 158 { |
| 167 | 159 |
| 168 if (*src > maxval || !result) | 160 #if defined (GFC_REAL_8_QUIET_NAN) |
| 169 { | 161 » » if (*src >= maxval) |
| 170 maxval = *src; | 162 » » { |
| 171 result = (GFC_INTEGER_4)n + 1; | 163 » » maxval = *src; |
| 172 } | 164 » » result = (GFC_INTEGER_4)n + 1; |
| 173 } | 165 » » break; |
| 166 » » } |
| 167 » } |
| 168 » for (; n < len; n++, src += delta) |
| 169 » { |
| 170 #endif |
| 171 » » if (*src > maxval) |
| 172 » » { |
| 173 » » maxval = *src; |
| 174 » » result = (GFC_INTEGER_4)n + 1; |
| 175 » » } |
| 176 » } |
| 174 *dest = result; | 177 *dest = result; |
| 175 } | 178 } |
| 176 } | 179 } |
| 177 /* Advance to the next element. */ | 180 /* Advance to the next element. */ |
| 178 count[0]++; | 181 count[0]++; |
| 179 base += sstride[0]; | 182 base += sstride[0]; |
| 180 dest += dstride[0]; | 183 dest += dstride[0]; |
| 181 n = 0; | 184 n = 0; |
| 182 while (count[n] == extent[n]) | 185 while (count[n] == extent[n]) |
| 183 { | 186 » { |
| 184 /* When we get to the end of a dimension, reset it and increment | 187 » /* When we get to the end of a dimension, reset it and increment |
| 185 the next dimension. */ | 188 » the next dimension. */ |
| 186 count[n] = 0; | 189 » count[n] = 0; |
| 187 /* We could precalculate these products, but this is a less | 190 » /* We could precalculate these products, but this is a less |
| 188 frequently used path so probably not worth it. */ | 191 » frequently used path so probably not worth it. */ |
| 189 base -= sstride[n] * extent[n]; | 192 » base -= sstride[n] * extent[n]; |
| 190 dest -= dstride[n] * extent[n]; | 193 » dest -= dstride[n] * extent[n]; |
| 191 n++; | 194 » n++; |
| 192 if (n == rank) | 195 » if (n == rank) |
| 193 { | 196 » { |
| 194 /* Break out of the look. */ | 197 » /* Break out of the look. */ |
| 195 continue_loop = 0; | 198 continue_loop = 0; |
| 196 break; | 199 break; |
| 197 } | 200 » } |
| 198 else | 201 » else |
| 199 { | 202 » { |
| 200 count[n]++; | 203 » count[n]++; |
| 201 base += sstride[n]; | 204 » base += sstride[n]; |
| 202 dest += dstride[n]; | 205 » dest += dstride[n]; |
| 203 } | 206 » } |
| 204 } | 207 » } |
| 205 } | 208 } |
| 206 } | 209 } |
| 207 | 210 |
| 208 | 211 |
| 209 extern void mmaxloc1_4_r8 (gfc_array_i4 * const restrict, | 212 extern void mmaxloc1_4_r8 (gfc_array_i4 * const restrict, |
| 210 gfc_array_r8 * const restrict, const index_type * const restrict, | 213 gfc_array_r8 * const restrict, const index_type * const restrict, |
| 211 gfc_array_l1 * const restrict); | 214 gfc_array_l1 * const restrict); |
| 212 export_proto(mmaxloc1_4_r8); | 215 export_proto(mmaxloc1_4_r8); |
| 213 | 216 |
| 214 void | 217 void |
| (...skipping 14 matching lines...) Expand all Loading... |
| 229 int dim; | 232 int dim; |
| 230 index_type n; | 233 index_type n; |
| 231 index_type len; | 234 index_type len; |
| 232 index_type delta; | 235 index_type delta; |
| 233 index_type mdelta; | 236 index_type mdelta; |
| 234 int mask_kind; | 237 int mask_kind; |
| 235 | 238 |
| 236 dim = (*pdim) - 1; | 239 dim = (*pdim) - 1; |
| 237 rank = GFC_DESCRIPTOR_RANK (array) - 1; | 240 rank = GFC_DESCRIPTOR_RANK (array) - 1; |
| 238 | 241 |
| 239 len = array->dim[dim].ubound + 1 - array->dim[dim].lbound; | 242 len = GFC_DESCRIPTOR_EXTENT(array,dim); |
| 240 if (len <= 0) | 243 if (len <= 0) |
| 241 return; | 244 return; |
| 242 | 245 |
| 243 mbase = mask->data; | 246 mbase = mask->data; |
| 244 | 247 |
| 245 mask_kind = GFC_DESCRIPTOR_SIZE (mask); | 248 mask_kind = GFC_DESCRIPTOR_SIZE (mask); |
| 246 | 249 |
| 247 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8 | 250 if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8 |
| 248 #ifdef HAVE_GFC_LOGICAL_16 | 251 #ifdef HAVE_GFC_LOGICAL_16 |
| 249 || mask_kind == 16 | 252 || mask_kind == 16 |
| 250 #endif | 253 #endif |
| 251 ) | 254 ) |
| 252 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind); | 255 mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind); |
| 253 else | 256 else |
| 254 runtime_error ("Funny sized logical array"); | 257 runtime_error ("Funny sized logical array"); |
| 255 | 258 |
| 256 delta = array->dim[dim].stride; | 259 delta = GFC_DESCRIPTOR_STRIDE(array,dim); |
| 257 mdelta = mask->dim[dim].stride * mask_kind; | 260 mdelta = GFC_DESCRIPTOR_STRIDE_BYTES(mask,dim); |
| 258 | 261 |
| 259 for (n = 0; n < dim; n++) | 262 for (n = 0; n < dim; n++) |
| 260 { | 263 { |
| 261 sstride[n] = array->dim[n].stride; | 264 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); |
| 262 mstride[n] = mask->dim[n].stride * mask_kind; | 265 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n); |
| 263 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound; | 266 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); |
| 264 | 267 |
| 265 if (extent[n] < 0) | 268 if (extent[n] < 0) |
| 266 extent[n] = 0; | 269 extent[n] = 0; |
| 267 | 270 |
| 268 } | 271 } |
| 269 for (n = dim; n < rank; n++) | 272 for (n = dim; n < rank; n++) |
| 270 { | 273 { |
| 271 sstride[n] = array->dim[n + 1].stride; | 274 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n + 1); |
| 272 mstride[n] = mask->dim[n + 1].stride * mask_kind; | 275 mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n + 1); |
| 273 extent[n] = | 276 extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1); |
| 274 array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound; | |
| 275 | 277 |
| 276 if (extent[n] < 0) | 278 if (extent[n] < 0) |
| 277 extent[n] = 0; | 279 extent[n] = 0; |
| 278 } | 280 } |
| 279 | 281 |
| 280 if (retarray->data == NULL) | 282 if (retarray->data == NULL) |
| 281 { | 283 { |
| 282 size_t alloc_size; | 284 size_t alloc_size, str; |
| 283 | 285 |
| 284 for (n = 0; n < rank; n++) | 286 for (n = 0; n < rank; n++) |
| 285 { | 287 » { |
| 286 retarray->dim[n].lbound = 0; | 288 » if (n == 0) |
| 287 retarray->dim[n].ubound = extent[n]-1; | 289 » str = 1; |
| 288 if (n == 0) | 290 » else |
| 289 retarray->dim[n].stride = 1; | 291 » str= GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1]; |
| 290 else | |
| 291 retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1]; | |
| 292 } | |
| 293 | 292 |
| 294 alloc_size = sizeof (GFC_INTEGER_4) * retarray->dim[rank-1].stride | 293 » GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str); |
| 294 |
| 295 » } |
| 296 |
| 297 alloc_size = sizeof (GFC_INTEGER_4) * GFC_DESCRIPTOR_STRIDE(retarray,rank-
1) |
| 295 * extent[rank-1]; | 298 * extent[rank-1]; |
| 296 | 299 |
| 297 retarray->offset = 0; | 300 retarray->offset = 0; |
| 298 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank; | 301 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank; |
| 299 | 302 |
| 300 if (alloc_size == 0) | 303 if (alloc_size == 0) |
| 301 { | 304 { |
| 302 /* Make sure we have a zero-sized array. */ | 305 /* Make sure we have a zero-sized array. */ |
| 303 » retarray->dim[0].lbound = 0; | 306 » GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); |
| 304 » retarray->dim[0].ubound = -1; | |
| 305 return; | 307 return; |
| 306 } | 308 } |
| 307 else | 309 else |
| 308 retarray->data = internal_malloc_size (alloc_size); | 310 retarray->data = internal_malloc_size (alloc_size); |
| 309 | 311 |
| 310 } | 312 } |
| 311 else | 313 else |
| 312 { | 314 { |
| 313 if (rank != GFC_DESCRIPTOR_RANK (retarray)) | 315 if (rank != GFC_DESCRIPTOR_RANK (retarray)) |
| 314 runtime_error ("rank of return array incorrect in MAXLOC intrinsic"); | 316 runtime_error ("rank of return array incorrect in MAXLOC intrinsic"); |
| 315 | 317 |
| 316 if (unlikely (compile_options.bounds_check)) | 318 if (unlikely (compile_options.bounds_check)) |
| 317 { | 319 { |
| 318 » for (n=0; n < rank; n++) | 320 » bounds_ifunction_return ((array_t *) retarray, extent, |
| 319 » { | 321 » » » » "return value", "MAXLOC"); |
| 320 » index_type ret_extent; | 322 » bounds_equal_extents ((array_t *) mask, (array_t *) array, |
| 321 | 323 » » » » "MASK argument", "MAXLOC"); |
| 322 » ret_extent = retarray->dim[n].ubound + 1 | |
| 323 » » - retarray->dim[n].lbound; | |
| 324 » if (extent[n] != ret_extent) | |
| 325 » » runtime_error ("Incorrect extent in return value of" | |
| 326 » » » " MAXLOC intrinsic in dimension %ld:" | |
| 327 » » » " is %ld, should be %ld", (long int) n + 1, | |
| 328 » » » (long int) ret_extent, (long int) extent[n]); | |
| 329 » } | |
| 330 for (n=0; n<= rank; n++) | |
| 331 { | |
| 332 index_type mask_extent, array_extent; | |
| 333 | |
| 334 » array_extent = array->dim[n].ubound + 1 - array->dim[n].lbound; | |
| 335 » mask_extent = mask->dim[n].ubound + 1 - mask->dim[n].lbound; | |
| 336 » if (array_extent != mask_extent) | |
| 337 » » runtime_error ("Incorrect extent in MASK argument of" | |
| 338 » » » " MAXLOC intrinsic in dimension %ld:" | |
| 339 » » » " is %ld, should be %ld", (long int) n + 1, | |
| 340 » » » (long int) mask_extent, (long int) array_extent); | |
| 341 » } | |
| 342 } | 324 } |
| 343 } | 325 } |
| 344 | 326 |
| 345 for (n = 0; n < rank; n++) | 327 for (n = 0; n < rank; n++) |
| 346 { | 328 { |
| 347 count[n] = 0; | 329 count[n] = 0; |
| 348 dstride[n] = retarray->dim[n].stride; | 330 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n); |
| 349 if (extent[n] <= 0) | 331 if (extent[n] <= 0) |
| 350 return; | 332 » return; |
| 351 } | 333 } |
| 352 | 334 |
| 353 dest = retarray->data; | 335 dest = retarray->data; |
| 354 base = array->data; | 336 base = array->data; |
| 355 | 337 |
| 356 while (base) | 338 while (base) |
| 357 { | 339 { |
| 358 const GFC_REAL_8 * restrict src; | 340 const GFC_REAL_8 * restrict src; |
| 359 const GFC_LOGICAL_1 * restrict msrc; | 341 const GFC_LOGICAL_1 * restrict msrc; |
| 360 GFC_INTEGER_4 result; | 342 GFC_INTEGER_4 result; |
| 361 src = base; | 343 src = base; |
| 362 msrc = mbase; | 344 msrc = mbase; |
| 363 { | 345 { |
| 364 | 346 |
| 365 GFC_REAL_8 maxval; | 347 » GFC_REAL_8 maxval; |
| 366 maxval = -GFC_REAL_8_HUGE; | 348 #if defined (GFC_REAL_8_INFINITY) |
| 367 result = 0; | 349 » maxval = -GFC_REAL_8_INFINITY; |
| 368 if (len <= 0) | 350 #else |
| 351 » maxval = -GFC_REAL_8_HUGE; |
| 352 #endif |
| 353 #if defined (GFC_REAL_8_QUIET_NAN) |
| 354 » GFC_INTEGER_4 result2 = 0; |
| 355 #endif |
| 356 » result = 0; |
| 357 » if (len <= 0) |
| 369 *dest = 0; | 358 *dest = 0; |
| 370 else | 359 else |
| 371 { | 360 { |
| 372 for (n = 0; n < len; n++, src += delta, msrc += mdelta) | 361 for (n = 0; n < len; n++, src += delta, msrc += mdelta) |
| 373 { | 362 { |
| 374 | 363 |
| 375 if (*msrc && (*src > maxval || !result)) | 364 » » if (*msrc) |
| 376 { | 365 » » { |
| 377 maxval = *src; | 366 #if defined (GFC_REAL_8_QUIET_NAN) |
| 378 result = (GFC_INTEGER_4)n + 1; | 367 » » if (!result2) |
| 379 } | 368 » » result2 = (GFC_INTEGER_4)n + 1; |
| 380 } | 369 » » if (*src >= maxval) |
| 370 #endif |
| 371 » » { |
| 372 » » » maxval = *src; |
| 373 » » » result = (GFC_INTEGER_4)n + 1; |
| 374 » » » break; |
| 375 » » } |
| 376 » » } |
| 377 » } |
| 378 #if defined (GFC_REAL_8_QUIET_NAN) |
| 379 » if (unlikely (n >= len)) |
| 380 » result = result2; |
| 381 » else |
| 382 #endif |
| 383 » for (; n < len; n++, src += delta, msrc += mdelta) |
| 384 » { |
| 385 » » if (*msrc && *src > maxval) |
| 386 » » { |
| 387 » » maxval = *src; |
| 388 » » result = (GFC_INTEGER_4)n + 1; |
| 389 » » } |
| 390 » } |
| 381 *dest = result; | 391 *dest = result; |
| 382 } | 392 } |
| 383 } | 393 } |
| 384 /* Advance to the next element. */ | 394 /* Advance to the next element. */ |
| 385 count[0]++; | 395 count[0]++; |
| 386 base += sstride[0]; | 396 base += sstride[0]; |
| 387 mbase += mstride[0]; | 397 mbase += mstride[0]; |
| 388 dest += dstride[0]; | 398 dest += dstride[0]; |
| 389 n = 0; | 399 n = 0; |
| 390 while (count[n] == extent[n]) | 400 while (count[n] == extent[n]) |
| 391 { | 401 » { |
| 392 /* When we get to the end of a dimension, reset it and increment | 402 » /* When we get to the end of a dimension, reset it and increment |
| 393 the next dimension. */ | 403 » the next dimension. */ |
| 394 count[n] = 0; | 404 » count[n] = 0; |
| 395 /* We could precalculate these products, but this is a less | 405 » /* We could precalculate these products, but this is a less |
| 396 frequently used path so probably not worth it. */ | 406 » frequently used path so probably not worth it. */ |
| 397 base -= sstride[n] * extent[n]; | 407 » base -= sstride[n] * extent[n]; |
| 398 mbase -= mstride[n] * extent[n]; | 408 » mbase -= mstride[n] * extent[n]; |
| 399 dest -= dstride[n] * extent[n]; | 409 » dest -= dstride[n] * extent[n]; |
| 400 n++; | 410 » n++; |
| 401 if (n == rank) | 411 » if (n == rank) |
| 402 { | 412 » { |
| 403 /* Break out of the look. */ | 413 » /* Break out of the look. */ |
| 404 base = NULL; | 414 » base = NULL; |
| 405 break; | 415 » break; |
| 406 } | 416 » } |
| 407 else | 417 » else |
| 408 { | 418 » { |
| 409 count[n]++; | 419 » count[n]++; |
| 410 base += sstride[n]; | 420 » base += sstride[n]; |
| 411 mbase += mstride[n]; | 421 » mbase += mstride[n]; |
| 412 dest += dstride[n]; | 422 » dest += dstride[n]; |
| 413 } | 423 » } |
| 414 } | 424 » } |
| 415 } | 425 } |
| 416 } | 426 } |
| 417 | 427 |
| 418 | 428 |
| 419 extern void smaxloc1_4_r8 (gfc_array_i4 * const restrict, | 429 extern void smaxloc1_4_r8 (gfc_array_i4 * const restrict, |
| 420 gfc_array_r8 * const restrict, const index_type * const restrict, | 430 gfc_array_r8 * const restrict, const index_type * const restrict, |
| 421 GFC_LOGICAL_4 *); | 431 GFC_LOGICAL_4 *); |
| 422 export_proto(smaxloc1_4_r8); | 432 export_proto(smaxloc1_4_r8); |
| 423 | 433 |
| 424 void | 434 void |
| 425 smaxloc1_4_r8 (gfc_array_i4 * const restrict retarray, | 435 smaxloc1_4_r8 (gfc_array_i4 * const restrict retarray, |
| 426 gfc_array_r8 * const restrict array, | 436 gfc_array_r8 * const restrict array, |
| 427 const index_type * const restrict pdim, | 437 const index_type * const restrict pdim, |
| 428 GFC_LOGICAL_4 * mask) | 438 GFC_LOGICAL_4 * mask) |
| 429 { | 439 { |
| 430 index_type count[GFC_MAX_DIMENSIONS]; | 440 index_type count[GFC_MAX_DIMENSIONS]; |
| 431 index_type extent[GFC_MAX_DIMENSIONS]; | 441 index_type extent[GFC_MAX_DIMENSIONS]; |
| 432 index_type sstride[GFC_MAX_DIMENSIONS]; | |
| 433 index_type dstride[GFC_MAX_DIMENSIONS]; | 442 index_type dstride[GFC_MAX_DIMENSIONS]; |
| 434 GFC_INTEGER_4 * restrict dest; | 443 GFC_INTEGER_4 * restrict dest; |
| 435 index_type rank; | 444 index_type rank; |
| 436 index_type n; | 445 index_type n; |
| 437 index_type dim; | 446 index_type dim; |
| 438 | 447 |
| 439 | 448 |
| 440 if (*mask) | 449 if (*mask) |
| 441 { | 450 { |
| 442 maxloc1_4_r8 (retarray, array, pdim); | 451 maxloc1_4_r8 (retarray, array, pdim); |
| 443 return; | 452 return; |
| 444 } | 453 } |
| 445 /* Make dim zero based to avoid confusion. */ | 454 /* Make dim zero based to avoid confusion. */ |
| 446 dim = (*pdim) - 1; | 455 dim = (*pdim) - 1; |
| 447 rank = GFC_DESCRIPTOR_RANK (array) - 1; | 456 rank = GFC_DESCRIPTOR_RANK (array) - 1; |
| 448 | 457 |
| 449 for (n = 0; n < dim; n++) | 458 for (n = 0; n < dim; n++) |
| 450 { | 459 { |
| 451 sstride[n] = array->dim[n].stride; | 460 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); |
| 452 extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound; | |
| 453 | 461 |
| 454 if (extent[n] <= 0) | 462 if (extent[n] <= 0) |
| 455 extent[n] = 0; | 463 extent[n] = 0; |
| 456 } | 464 } |
| 457 | 465 |
| 458 for (n = dim; n < rank; n++) | 466 for (n = dim; n < rank; n++) |
| 459 { | 467 { |
| 460 sstride[n] = array->dim[n + 1].stride; | |
| 461 extent[n] = | 468 extent[n] = |
| 462 array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound; | 469 » GFC_DESCRIPTOR_EXTENT(array,n + 1); |
| 463 | 470 |
| 464 if (extent[n] <= 0) | 471 if (extent[n] <= 0) |
| 465 extent[n] = 0; | 472 » extent[n] = 0; |
| 466 } | 473 } |
| 467 | 474 |
| 468 if (retarray->data == NULL) | 475 if (retarray->data == NULL) |
| 469 { | 476 { |
| 470 size_t alloc_size; | 477 size_t alloc_size, str; |
| 471 | 478 |
| 472 for (n = 0; n < rank; n++) | 479 for (n = 0; n < rank; n++) |
| 473 { | 480 » { |
| 474 retarray->dim[n].lbound = 0; | 481 » if (n == 0) |
| 475 retarray->dim[n].ubound = extent[n]-1; | 482 » str = 1; |
| 476 if (n == 0) | 483 » else |
| 477 retarray->dim[n].stride = 1; | 484 » str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1]; |
| 478 else | 485 |
| 479 retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1]; | 486 » GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str); |
| 480 } | 487 |
| 488 » } |
| 481 | 489 |
| 482 retarray->offset = 0; | 490 retarray->offset = 0; |
| 483 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank; | 491 retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank; |
| 484 | 492 |
| 485 alloc_size = sizeof (GFC_INTEGER_4) * retarray->dim[rank-1].stride | 493 alloc_size = sizeof (GFC_INTEGER_4) * GFC_DESCRIPTOR_STRIDE(retarray,rank-
1) |
| 486 * extent[rank-1]; | 494 * extent[rank-1]; |
| 487 | 495 |
| 488 if (alloc_size == 0) | 496 if (alloc_size == 0) |
| 489 { | 497 { |
| 490 /* Make sure we have a zero-sized array. */ | 498 /* Make sure we have a zero-sized array. */ |
| 491 » retarray->dim[0].lbound = 0; | 499 » GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); |
| 492 » retarray->dim[0].ubound = -1; | |
| 493 return; | 500 return; |
| 494 } | 501 } |
| 495 else | 502 else |
| 496 retarray->data = internal_malloc_size (alloc_size); | 503 retarray->data = internal_malloc_size (alloc_size); |
| 497 } | 504 } |
| 498 else | 505 else |
| 499 { | 506 { |
| 500 if (rank != GFC_DESCRIPTOR_RANK (retarray)) | 507 if (rank != GFC_DESCRIPTOR_RANK (retarray)) |
| 501 runtime_error ("rank of return array incorrect in" | 508 runtime_error ("rank of return array incorrect in" |
| 502 " MAXLOC intrinsic: is %ld, should be %ld", | 509 " MAXLOC intrinsic: is %ld, should be %ld", |
| 503 (long int) (GFC_DESCRIPTOR_RANK (retarray)), | 510 (long int) (GFC_DESCRIPTOR_RANK (retarray)), |
| 504 (long int) rank); | 511 (long int) rank); |
| 505 | 512 |
| 506 if (unlikely (compile_options.bounds_check)) | 513 if (unlikely (compile_options.bounds_check)) |
| 507 { | 514 { |
| 508 for (n=0; n < rank; n++) | 515 for (n=0; n < rank; n++) |
| 509 { | 516 { |
| 510 index_type ret_extent; | 517 index_type ret_extent; |
| 511 | 518 |
| 512 » ret_extent = retarray->dim[n].ubound + 1 | 519 » ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,n); |
| 513 » » - retarray->dim[n].lbound; | |
| 514 if (extent[n] != ret_extent) | 520 if (extent[n] != ret_extent) |
| 515 runtime_error ("Incorrect extent in return value of" | 521 runtime_error ("Incorrect extent in return value of" |
| 516 " MAXLOC intrinsic in dimension %ld:" | 522 " MAXLOC intrinsic in dimension %ld:" |
| 517 " is %ld, should be %ld", (long int) n + 1, | 523 " is %ld, should be %ld", (long int) n + 1, |
| 518 (long int) ret_extent, (long int) extent[n]); | 524 (long int) ret_extent, (long int) extent[n]); |
| 519 } | 525 } |
| 520 } | 526 } |
| 521 } | 527 } |
| 522 | 528 |
| 523 for (n = 0; n < rank; n++) | 529 for (n = 0; n < rank; n++) |
| 524 { | 530 { |
| 525 count[n] = 0; | 531 count[n] = 0; |
| 526 dstride[n] = retarray->dim[n].stride; | 532 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n); |
| 527 } | 533 } |
| 528 | 534 |
| 529 dest = retarray->data; | 535 dest = retarray->data; |
| 530 | 536 |
| 531 while(1) | 537 while(1) |
| 532 { | 538 { |
| 533 *dest = 0; | 539 *dest = 0; |
| 534 count[0]++; | 540 count[0]++; |
| 535 dest += dstride[0]; | 541 dest += dstride[0]; |
| 536 n = 0; | 542 n = 0; |
| 537 while (count[n] == extent[n]) | 543 while (count[n] == extent[n]) |
| 538 { | 544 » { |
| 539 /* When we get to the end of a dimension, reset it and increment | 545 /* When we get to the end of a dimension, reset it and increment |
| 540 the next dimension. */ | 546 » the next dimension. */ |
| 541 count[n] = 0; | 547 » count[n] = 0; |
| 542 /* We could precalculate these products, but this is a less | 548 » /* We could precalculate these products, but this is a less |
| 543 frequently used path so probably not worth it. */ | 549 » frequently used path so probably not worth it. */ |
| 544 dest -= dstride[n] * extent[n]; | 550 » dest -= dstride[n] * extent[n]; |
| 545 n++; | 551 » n++; |
| 546 if (n == rank) | 552 » if (n == rank) |
| 547 return; | 553 return; |
| 548 else | 554 » else |
| 549 { | 555 » { |
| 550 count[n]++; | 556 » count[n]++; |
| 551 dest += dstride[n]; | 557 » dest += dstride[n]; |
| 552 } | 558 » } |
| 553 } | 559 } |
| 554 } | 560 } |
| 555 } | 561 } |
| 556 | 562 |
| 557 #endif | 563 #endif |
| OLD | NEW |