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 |