OSDN Git Service

f3470e8b951c7148a3857766a5dd7b38c4a2b3dc
[pf3gnuchains/gcc-fork.git] / libgfortran / generated / maxval_r4.c
1 /* Implementation of the MAXVAL intrinsic
2    Copyright 2002, 2007 Free Software Foundation, Inc.
3    Contributed by Paul Brook <paul@nowt.org>
4
5 This file is part of the GNU Fortran 95 runtime library (libgfortran).
6
7 Libgfortran is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file.  (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combine
19 executable.)
20
21 Libgfortran is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public
27 License along with libgfortran; see the file COPYING.  If not,
28 write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, USA.  */
30
31 #include "libgfortran.h"
32 #include <stdlib.h>
33 #include <assert.h>
34
35
36 #if defined (HAVE_GFC_REAL_4) && defined (HAVE_GFC_REAL_4)
37
38
39 extern void maxval_r4 (gfc_array_r4 * const restrict, 
40         gfc_array_r4 * const restrict, const index_type * const restrict);
41 export_proto(maxval_r4);
42
43 void
44 maxval_r4 (gfc_array_r4 * const restrict retarray, 
45         gfc_array_r4 * const restrict array, 
46         const index_type * const restrict pdim)
47 {
48   index_type count[GFC_MAX_DIMENSIONS];
49   index_type extent[GFC_MAX_DIMENSIONS];
50   index_type sstride[GFC_MAX_DIMENSIONS];
51   index_type dstride[GFC_MAX_DIMENSIONS];
52   const GFC_REAL_4 * restrict base;
53   GFC_REAL_4 * restrict dest;
54   index_type rank;
55   index_type n;
56   index_type len;
57   index_type delta;
58   index_type dim;
59
60   /* Make dim zero based to avoid confusion.  */
61   dim = (*pdim) - 1;
62   rank = GFC_DESCRIPTOR_RANK (array) - 1;
63
64   len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
65   delta = array->dim[dim].stride;
66
67   for (n = 0; n < dim; n++)
68     {
69       sstride[n] = array->dim[n].stride;
70       extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
71
72       if (extent[n] < 0)
73         extent[n] = 0;
74     }
75   for (n = dim; n < rank; n++)
76     {
77       sstride[n] = array->dim[n + 1].stride;
78       extent[n] =
79         array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
80
81       if (extent[n] < 0)
82         extent[n] = 0;
83     }
84
85   if (retarray->data == NULL)
86     {
87       size_t alloc_size;
88
89       for (n = 0; n < rank; n++)
90         {
91           retarray->dim[n].lbound = 0;
92           retarray->dim[n].ubound = extent[n]-1;
93           if (n == 0)
94             retarray->dim[n].stride = 1;
95           else
96             retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1];
97         }
98
99       retarray->offset = 0;
100       retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
101
102       alloc_size = sizeof (GFC_REAL_4) * retarray->dim[rank-1].stride
103                    * extent[rank-1];
104
105       if (alloc_size == 0)
106         {
107           /* Make sure we have a zero-sized array.  */
108           retarray->dim[0].lbound = 0;
109           retarray->dim[0].ubound = -1;
110           return;
111         }
112       else
113         retarray->data = internal_malloc_size (alloc_size);
114     }
115   else
116     {
117       if (rank != GFC_DESCRIPTOR_RANK (retarray))
118         runtime_error ("rank of return array incorrect in"
119                        " MAXVAL intrinsic: is %ld, should be %ld",
120                        (long int) (GFC_DESCRIPTOR_RANK (retarray)),
121                        (long int) rank);
122
123       if (compile_options.bounds_check)
124         {
125           for (n=0; n < rank; n++)
126             {
127               index_type ret_extent;
128
129               ret_extent = retarray->dim[n].ubound + 1
130                 - retarray->dim[n].lbound;
131               if (extent[n] != ret_extent)
132                 runtime_error ("Incorrect extent in return value of"
133                                " MAXVAL intrinsic in dimension %ld:"
134                                " is %ld, should be %ld", (long int) n + 1,
135                                (long int) ret_extent, (long int) extent[n]);
136             }
137         }
138     }
139
140   for (n = 0; n < rank; n++)
141     {
142       count[n] = 0;
143       dstride[n] = retarray->dim[n].stride;
144       if (extent[n] <= 0)
145         len = 0;
146     }
147
148   base = array->data;
149   dest = retarray->data;
150
151   while (base)
152     {
153       const GFC_REAL_4 * restrict src;
154       GFC_REAL_4 result;
155       src = base;
156       {
157
158   result = -GFC_REAL_4_HUGE;
159         if (len <= 0)
160           *dest = -GFC_REAL_4_HUGE;
161         else
162           {
163             for (n = 0; n < len; n++, src += delta)
164               {
165
166   if (*src > result)
167     result = *src;
168           }
169             *dest = result;
170           }
171       }
172       /* Advance to the next element.  */
173       count[0]++;
174       base += sstride[0];
175       dest += dstride[0];
176       n = 0;
177       while (count[n] == extent[n])
178         {
179           /* When we get to the end of a dimension, reset it and increment
180              the next dimension.  */
181           count[n] = 0;
182           /* We could precalculate these products, but this is a less
183              frequently used path so probably not worth it.  */
184           base -= sstride[n] * extent[n];
185           dest -= dstride[n] * extent[n];
186           n++;
187           if (n == rank)
188             {
189               /* Break out of the look.  */
190               base = NULL;
191               break;
192             }
193           else
194             {
195               count[n]++;
196               base += sstride[n];
197               dest += dstride[n];
198             }
199         }
200     }
201 }
202
203
204 extern void mmaxval_r4 (gfc_array_r4 * const restrict, 
205         gfc_array_r4 * const restrict, const index_type * const restrict,
206         gfc_array_l1 * const restrict);
207 export_proto(mmaxval_r4);
208
209 void
210 mmaxval_r4 (gfc_array_r4 * const restrict retarray, 
211         gfc_array_r4 * const restrict array, 
212         const index_type * const restrict pdim, 
213         gfc_array_l1 * const restrict mask)
214 {
215   index_type count[GFC_MAX_DIMENSIONS];
216   index_type extent[GFC_MAX_DIMENSIONS];
217   index_type sstride[GFC_MAX_DIMENSIONS];
218   index_type dstride[GFC_MAX_DIMENSIONS];
219   index_type mstride[GFC_MAX_DIMENSIONS];
220   GFC_REAL_4 * restrict dest;
221   const GFC_REAL_4 * restrict base;
222   const GFC_LOGICAL_1 * restrict mbase;
223   int rank;
224   int dim;
225   index_type n;
226   index_type len;
227   index_type delta;
228   index_type mdelta;
229   int mask_kind;
230
231   dim = (*pdim) - 1;
232   rank = GFC_DESCRIPTOR_RANK (array) - 1;
233
234   len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
235   if (len <= 0)
236     return;
237
238   mbase = mask->data;
239
240   mask_kind = GFC_DESCRIPTOR_SIZE (mask);
241
242   if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
243 #ifdef HAVE_GFC_LOGICAL_16
244       || mask_kind == 16
245 #endif
246       )
247     mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
248   else
249     runtime_error ("Funny sized logical array");
250
251   delta = array->dim[dim].stride;
252   mdelta = mask->dim[dim].stride * mask_kind;
253
254   for (n = 0; n < dim; n++)
255     {
256       sstride[n] = array->dim[n].stride;
257       mstride[n] = mask->dim[n].stride * mask_kind;
258       extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
259
260       if (extent[n] < 0)
261         extent[n] = 0;
262
263     }
264   for (n = dim; n < rank; n++)
265     {
266       sstride[n] = array->dim[n + 1].stride;
267       mstride[n] = mask->dim[n + 1].stride * mask_kind;
268       extent[n] =
269         array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
270
271       if (extent[n] < 0)
272         extent[n] = 0;
273     }
274
275   if (retarray->data == NULL)
276     {
277       size_t alloc_size;
278
279       for (n = 0; n < rank; n++)
280         {
281           retarray->dim[n].lbound = 0;
282           retarray->dim[n].ubound = extent[n]-1;
283           if (n == 0)
284             retarray->dim[n].stride = 1;
285           else
286             retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1];
287         }
288
289       alloc_size = sizeof (GFC_REAL_4) * retarray->dim[rank-1].stride
290                    * extent[rank-1];
291
292       retarray->offset = 0;
293       retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
294
295       if (alloc_size == 0)
296         {
297           /* Make sure we have a zero-sized array.  */
298           retarray->dim[0].lbound = 0;
299           retarray->dim[0].ubound = -1;
300           return;
301         }
302       else
303         retarray->data = internal_malloc_size (alloc_size);
304
305     }
306   else
307     {
308       if (rank != GFC_DESCRIPTOR_RANK (retarray))
309         runtime_error ("rank of return array incorrect in MAXVAL intrinsic");
310
311       if (compile_options.bounds_check)
312         {
313           for (n=0; n < rank; n++)
314             {
315               index_type ret_extent;
316
317               ret_extent = retarray->dim[n].ubound + 1
318                 - retarray->dim[n].lbound;
319               if (extent[n] != ret_extent)
320                 runtime_error ("Incorrect extent in return value of"
321                                " MAXVAL intrinsic in dimension %ld:"
322                                " is %ld, should be %ld", (long int) n + 1,
323                                (long int) ret_extent, (long int) extent[n]);
324             }
325           for (n=0; n<= rank; n++)
326             {
327               index_type mask_extent, array_extent;
328
329               array_extent = array->dim[n].ubound + 1 - array->dim[n].lbound;
330               mask_extent = mask->dim[n].ubound + 1 - mask->dim[n].lbound;
331               if (array_extent != mask_extent)
332                 runtime_error ("Incorrect extent in MASK argument of"
333                                " MAXVAL intrinsic in dimension %ld:"
334                                " is %ld, should be %ld", (long int) n + 1,
335                                (long int) mask_extent, (long int) array_extent);
336             }
337         }
338     }
339
340   for (n = 0; n < rank; n++)
341     {
342       count[n] = 0;
343       dstride[n] = retarray->dim[n].stride;
344       if (extent[n] <= 0)
345         return;
346     }
347
348   dest = retarray->data;
349   base = array->data;
350
351   while (base)
352     {
353       const GFC_REAL_4 * restrict src;
354       const GFC_LOGICAL_1 * restrict msrc;
355       GFC_REAL_4 result;
356       src = base;
357       msrc = mbase;
358       {
359
360   result = -GFC_REAL_4_HUGE;
361         if (len <= 0)
362           *dest = -GFC_REAL_4_HUGE;
363         else
364           {
365             for (n = 0; n < len; n++, src += delta, msrc += mdelta)
366               {
367
368   if (*msrc && *src > result)
369     result = *src;
370               }
371             *dest = result;
372           }
373       }
374       /* Advance to the next element.  */
375       count[0]++;
376       base += sstride[0];
377       mbase += mstride[0];
378       dest += dstride[0];
379       n = 0;
380       while (count[n] == extent[n])
381         {
382           /* When we get to the end of a dimension, reset it and increment
383              the next dimension.  */
384           count[n] = 0;
385           /* We could precalculate these products, but this is a less
386              frequently used path so probably not worth it.  */
387           base -= sstride[n] * extent[n];
388           mbase -= mstride[n] * extent[n];
389           dest -= dstride[n] * extent[n];
390           n++;
391           if (n == rank)
392             {
393               /* Break out of the look.  */
394               base = NULL;
395               break;
396             }
397           else
398             {
399               count[n]++;
400               base += sstride[n];
401               mbase += mstride[n];
402               dest += dstride[n];
403             }
404         }
405     }
406 }
407
408
409 extern void smaxval_r4 (gfc_array_r4 * const restrict, 
410         gfc_array_r4 * const restrict, const index_type * const restrict,
411         GFC_LOGICAL_4 *);
412 export_proto(smaxval_r4);
413
414 void
415 smaxval_r4 (gfc_array_r4 * const restrict retarray, 
416         gfc_array_r4 * const restrict array, 
417         const index_type * const restrict pdim, 
418         GFC_LOGICAL_4 * mask)
419 {
420   index_type count[GFC_MAX_DIMENSIONS];
421   index_type extent[GFC_MAX_DIMENSIONS];
422   index_type sstride[GFC_MAX_DIMENSIONS];
423   index_type dstride[GFC_MAX_DIMENSIONS];
424   GFC_REAL_4 * restrict dest;
425   index_type rank;
426   index_type n;
427   index_type dim;
428
429
430   if (*mask)
431     {
432       maxval_r4 (retarray, array, pdim);
433       return;
434     }
435   /* Make dim zero based to avoid confusion.  */
436   dim = (*pdim) - 1;
437   rank = GFC_DESCRIPTOR_RANK (array) - 1;
438
439   for (n = 0; n < dim; n++)
440     {
441       sstride[n] = array->dim[n].stride;
442       extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
443
444       if (extent[n] <= 0)
445         extent[n] = 0;
446     }
447
448   for (n = dim; n < rank; n++)
449     {
450       sstride[n] = array->dim[n + 1].stride;
451       extent[n] =
452         array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
453
454       if (extent[n] <= 0)
455         extent[n] = 0;
456     }
457
458   if (retarray->data == NULL)
459     {
460       size_t alloc_size;
461
462       for (n = 0; n < rank; n++)
463         {
464           retarray->dim[n].lbound = 0;
465           retarray->dim[n].ubound = extent[n]-1;
466           if (n == 0)
467             retarray->dim[n].stride = 1;
468           else
469             retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1];
470         }
471
472       retarray->offset = 0;
473       retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
474
475       alloc_size = sizeof (GFC_REAL_4) * retarray->dim[rank-1].stride
476                    * extent[rank-1];
477
478       if (alloc_size == 0)
479         {
480           /* Make sure we have a zero-sized array.  */
481           retarray->dim[0].lbound = 0;
482           retarray->dim[0].ubound = -1;
483           return;
484         }
485       else
486         retarray->data = internal_malloc_size (alloc_size);
487     }
488   else
489     {
490       if (rank != GFC_DESCRIPTOR_RANK (retarray))
491         runtime_error ("rank of return array incorrect in"
492                        " MAXVAL intrinsic: is %ld, should be %ld",
493                        (long int) (GFC_DESCRIPTOR_RANK (retarray)),
494                        (long int) rank);
495
496       if (compile_options.bounds_check)
497         {
498           for (n=0; n < rank; n++)
499             {
500               index_type ret_extent;
501
502               ret_extent = retarray->dim[n].ubound + 1
503                 - retarray->dim[n].lbound;
504               if (extent[n] != ret_extent)
505                 runtime_error ("Incorrect extent in return value of"
506                                " MAXVAL intrinsic in dimension %ld:"
507                                " is %ld, should be %ld", (long int) n + 1,
508                                (long int) ret_extent, (long int) extent[n]);
509             }
510         }
511     }
512
513   for (n = 0; n < rank; n++)
514     {
515       count[n] = 0;
516       dstride[n] = retarray->dim[n].stride;
517     }
518
519   dest = retarray->data;
520
521   while(1)
522     {
523       *dest = -GFC_REAL_4_HUGE;
524       count[0]++;
525       dest += dstride[0];
526       n = 0;
527       while (count[n] == extent[n])
528         {
529           /* When we get to the end of a dimension, reset it and increment
530              the next dimension.  */
531           count[n] = 0;
532           /* We could precalculate these products, but this is a less
533              frequently used path so probably not worth it.  */
534           dest -= dstride[n] * extent[n];
535           n++;
536           if (n == rank)
537             return;
538           else
539             {
540               count[n]++;
541               dest += dstride[n];
542             }
543         }
544     }
545 }
546
547 #endif