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 |