OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libgfortran/] [generated/] [minval_r8.c] - Blame information for rev 14

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.