OSDN Git Service

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