OSDN Git Service

94d6789a2eb60311f10be0db75b9189cce6e0107
[pf3gnuchains/gcc-fork.git] / libgfortran / generated / maxval_r16.c
1 /* Implementation of the MAXVAL intrinsic
2    Copyright 2002 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 "config.h"
32 #include <stdlib.h>
33 #include <assert.h>
34 #include <float.h>
35 #include "libgfortran.h"
36
37
38 #if defined (HAVE_GFC_REAL_16) && defined (HAVE_GFC_REAL_16)
39
40
41 extern void maxval_r16 (gfc_array_r16 * const restrict, 
42         gfc_array_r16 * const restrict, const index_type * const restrict);
43 export_proto(maxval_r16);
44
45 void
46 maxval_r16 (gfc_array_r16 * const restrict retarray, 
47         gfc_array_r16 * const restrict array, 
48         const index_type * const restrict pdim)
49 {
50   index_type count[GFC_MAX_DIMENSIONS];
51   index_type extent[GFC_MAX_DIMENSIONS];
52   index_type sstride[GFC_MAX_DIMENSIONS];
53   index_type dstride[GFC_MAX_DIMENSIONS];
54   const GFC_REAL_16 * restrict base;
55   GFC_REAL_16 * restrict dest;
56   index_type rank;
57   index_type n;
58   index_type len;
59   index_type delta;
60   index_type dim;
61
62   /* Make dim zero based to avoid confusion.  */
63   dim = (*pdim) - 1;
64   rank = GFC_DESCRIPTOR_RANK (array) - 1;
65
66   len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
67   delta = array->dim[dim].stride;
68
69   for (n = 0; n < dim; n++)
70     {
71       sstride[n] = array->dim[n].stride;
72       extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
73     }
74   for (n = dim; n < rank; n++)
75     {
76       sstride[n] = array->dim[n + 1].stride;
77       extent[n] =
78         array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
79     }
80
81   if (retarray->data == NULL)
82     {
83       for (n = 0; n < rank; n++)
84         {
85           retarray->dim[n].lbound = 0;
86           retarray->dim[n].ubound = extent[n]-1;
87           if (n == 0)
88             retarray->dim[n].stride = 1;
89           else
90             retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1];
91         }
92
93       retarray->data
94          = internal_malloc_size (sizeof (GFC_REAL_16)
95                                  * retarray->dim[rank-1].stride
96                                  * extent[rank-1]);
97       retarray->offset = 0;
98       retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
99     }
100   else
101     {
102       if (rank != GFC_DESCRIPTOR_RANK (retarray))
103         runtime_error ("rank of return array incorrect");
104     }
105
106   for (n = 0; n < rank; n++)
107     {
108       count[n] = 0;
109       dstride[n] = retarray->dim[n].stride;
110       if (extent[n] <= 0)
111         len = 0;
112     }
113
114   base = array->data;
115   dest = retarray->data;
116
117   while (base)
118     {
119       const GFC_REAL_16 * restrict src;
120       GFC_REAL_16 result;
121       src = base;
122       {
123
124   result = -GFC_REAL_16_HUGE;
125         if (len <= 0)
126           *dest = -GFC_REAL_16_HUGE;
127         else
128           {
129             for (n = 0; n < len; n++, src += delta)
130               {
131
132   if (*src > result)
133     result = *src;
134           }
135             *dest = result;
136           }
137       }
138       /* Advance to the next element.  */
139       count[0]++;
140       base += sstride[0];
141       dest += dstride[0];
142       n = 0;
143       while (count[n] == extent[n])
144         {
145           /* When we get to the end of a dimension, reset it and increment
146              the next dimension.  */
147           count[n] = 0;
148           /* We could precalculate these products, but this is a less
149              frequently used path so probably not worth it.  */
150           base -= sstride[n] * extent[n];
151           dest -= dstride[n] * extent[n];
152           n++;
153           if (n == rank)
154             {
155               /* Break out of the look.  */
156               base = NULL;
157               break;
158             }
159           else
160             {
161               count[n]++;
162               base += sstride[n];
163               dest += dstride[n];
164             }
165         }
166     }
167 }
168
169
170 extern void mmaxval_r16 (gfc_array_r16 * const restrict, 
171         gfc_array_r16 * const restrict, const index_type * const restrict,
172         gfc_array_l4 * const restrict);
173 export_proto(mmaxval_r16);
174
175 void
176 mmaxval_r16 (gfc_array_r16 * const restrict retarray, 
177         gfc_array_r16 * const restrict array, 
178         const index_type * const restrict pdim, 
179         gfc_array_l4 * const restrict mask)
180 {
181   index_type count[GFC_MAX_DIMENSIONS];
182   index_type extent[GFC_MAX_DIMENSIONS];
183   index_type sstride[GFC_MAX_DIMENSIONS];
184   index_type dstride[GFC_MAX_DIMENSIONS];
185   index_type mstride[GFC_MAX_DIMENSIONS];
186   GFC_REAL_16 * restrict dest;
187   const GFC_REAL_16 * restrict base;
188   const GFC_LOGICAL_4 * restrict mbase;
189   int rank;
190   int dim;
191   index_type n;
192   index_type len;
193   index_type delta;
194   index_type mdelta;
195
196   dim = (*pdim) - 1;
197   rank = GFC_DESCRIPTOR_RANK (array) - 1;
198
199   len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
200   if (len <= 0)
201     return;
202   delta = array->dim[dim].stride;
203   mdelta = mask->dim[dim].stride;
204
205   for (n = 0; n < dim; n++)
206     {
207       sstride[n] = array->dim[n].stride;
208       mstride[n] = mask->dim[n].stride;
209       extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
210     }
211   for (n = dim; n < rank; n++)
212     {
213       sstride[n] = array->dim[n + 1].stride;
214       mstride[n] = mask->dim[n + 1].stride;
215       extent[n] =
216         array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
217     }
218
219   if (retarray->data == NULL)
220     {
221       for (n = 0; n < rank; n++)
222         {
223           retarray->dim[n].lbound = 0;
224           retarray->dim[n].ubound = extent[n]-1;
225           if (n == 0)
226             retarray->dim[n].stride = 1;
227           else
228             retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1];
229         }
230
231       retarray->data
232          = internal_malloc_size (sizeof (GFC_REAL_16)
233                                  * retarray->dim[rank-1].stride
234                                  * extent[rank-1]);
235       retarray->offset = 0;
236       retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
237     }
238   else
239     {
240       if (rank != GFC_DESCRIPTOR_RANK (retarray))
241         runtime_error ("rank of return array incorrect");
242     }
243
244   for (n = 0; n < rank; n++)
245     {
246       count[n] = 0;
247       dstride[n] = retarray->dim[n].stride;
248       if (extent[n] <= 0)
249         return;
250     }
251
252   dest = retarray->data;
253   base = array->data;
254   mbase = mask->data;
255
256   if (GFC_DESCRIPTOR_SIZE (mask) != 4)
257     {
258       /* This allows the same loop to be used for all logical types.  */
259       assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
260       for (n = 0; n < rank; n++)
261         mstride[n] <<= 1;
262       mdelta <<= 1;
263       mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
264     }
265
266   while (base)
267     {
268       const GFC_REAL_16 * restrict src;
269       const GFC_LOGICAL_4 * restrict msrc;
270       GFC_REAL_16 result;
271       src = base;
272       msrc = mbase;
273       {
274
275   result = -GFC_REAL_16_HUGE;
276         if (len <= 0)
277           *dest = -GFC_REAL_16_HUGE;
278         else
279           {
280             for (n = 0; n < len; n++, src += delta, msrc += mdelta)
281               {
282
283   if (*msrc && *src > result)
284     result = *src;
285               }
286             *dest = result;
287           }
288       }
289       /* Advance to the next element.  */
290       count[0]++;
291       base += sstride[0];
292       mbase += mstride[0];
293       dest += dstride[0];
294       n = 0;
295       while (count[n] == extent[n])
296         {
297           /* When we get to the end of a dimension, reset it and increment
298              the next dimension.  */
299           count[n] = 0;
300           /* We could precalculate these products, but this is a less
301              frequently used path so probably not worth it.  */
302           base -= sstride[n] * extent[n];
303           mbase -= mstride[n] * extent[n];
304           dest -= dstride[n] * extent[n];
305           n++;
306           if (n == rank)
307             {
308               /* Break out of the look.  */
309               base = NULL;
310               break;
311             }
312           else
313             {
314               count[n]++;
315               base += sstride[n];
316               mbase += mstride[n];
317               dest += dstride[n];
318             }
319         }
320     }
321 }
322
323
324 extern void smaxval_r16 (gfc_array_r16 * const restrict, 
325         gfc_array_r16 * const restrict, const index_type * const restrict,
326         GFC_LOGICAL_4 *);
327 export_proto(smaxval_r16);
328
329 void
330 smaxval_r16 (gfc_array_r16 * const restrict retarray, 
331         gfc_array_r16 * const restrict array, 
332         const index_type * const restrict pdim, 
333         GFC_LOGICAL_4 * mask)
334 {
335   index_type rank;
336   index_type n;
337   index_type dstride;
338   GFC_REAL_16 *dest;
339
340   if (*mask)
341     {
342       maxval_r16 (retarray, array, pdim);
343       return;
344     }
345     rank = GFC_DESCRIPTOR_RANK (array);
346   if (rank <= 0)
347     runtime_error ("Rank of array needs to be > 0");
348
349   if (retarray->data == NULL)
350     {
351       retarray->dim[0].lbound = 0;
352       retarray->dim[0].ubound = rank-1;
353       retarray->dim[0].stride = 1;
354       retarray->dtype = (retarray->dtype & ~GFC_DTYPE_RANK_MASK) | 1;
355       retarray->offset = 0;
356       retarray->data = internal_malloc_size (sizeof (GFC_REAL_16) * rank);
357     }
358   else
359     {
360       if (GFC_DESCRIPTOR_RANK (retarray) != 1)
361         runtime_error ("rank of return array does not equal 1");
362
363       if (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound != rank)
364         runtime_error ("dimension of return array incorrect");
365     }
366
367     dstride = retarray->dim[0].stride;
368     dest = retarray->data;
369
370     for (n = 0; n < rank; n++)
371       dest[n * dstride] = -GFC_REAL_16_HUGE ;
372 }
373
374 #endif