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