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

Subversion Repositories scarts

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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