OSDN Git Service

b86a80c41cadfcd9db4fab7381e7d7fc9c14a186
[pf3gnuchains/gcc-fork.git] / libgfortran / m4 / eoshift3.m4
1 `/* Implementation of the EOSHIFT 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 (libgfor).
6
7 Libgfor is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 Ligbfor 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 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with libgfor; see the file COPYING.LIB.  If not,
19 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 #include "config.h"
23 #include <stdlib.h>
24 #include <assert.h>
25 #include <string.h>
26 #include "libgfortran.h"'
27 include(types.m4)dnl
28 define(htype_kind, regexp(file, `_\([0-9]+\)\.', `\1'))dnl
29 define(htype_code,`i'rtype_name)dnl
30 define(htype,get_arraytype(i,htype_kind))dnl
31 define(htype_name, get_typename(i,htype_kind))dnl
32
33 static const char zeros[16] =
34   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
35
36 void
37 `__eoshift3_'htype_kind (gfc_array_char * ret, gfc_array_char * array,
38     htype * h, const gfc_array_char * bound, htype_name * pwhich)
39 {
40   /* r.* indicates the return array.  */
41   index_type rstride[GFC_MAX_DIMENSIONS - 1];
42   index_type rstride0;
43   index_type roffset;
44   char *rptr;
45   char *dest;
46   /* s.* indicates the source array.  */
47   index_type sstride[GFC_MAX_DIMENSIONS - 1];
48   index_type sstride0;
49   index_type soffset;
50   const char *sptr;
51   const char *src;
52 `  /* h.* indicates the shift array.  */'
53   index_type hstride[GFC_MAX_DIMENSIONS - 1];
54   index_type hstride0;
55   const htype_name *hptr;
56   /* b.* indicates the bound array.  */
57   index_type bstride[GFC_MAX_DIMENSIONS - 1];
58   index_type bstride0;
59   const char *bptr;
60
61   index_type count[GFC_MAX_DIMENSIONS - 1];
62   index_type extent[GFC_MAX_DIMENSIONS - 1];
63   index_type dim;
64   index_type size;
65   index_type len;
66   index_type n;
67   int which;
68   htype_name sh;
69   htype_name delta;
70
71   if (pwhich)
72     which = *pwhich - 1;
73   else
74     which = 0;
75
76   size = GFC_DESCRIPTOR_SIZE (ret);
77
78   extent[0] = 1;
79   count[0] = 0;
80   size = GFC_DESCRIPTOR_SIZE (array);
81   n = 0;
82   for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
83     {
84       if (dim == which)
85         {
86           roffset = ret->dim[dim].stride * size;
87           if (roffset == 0)
88             roffset = size;
89           soffset = array->dim[dim].stride * size;
90           if (soffset == 0)
91             soffset = size;
92           len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
93         }
94       else
95         {
96           count[n] = 0;
97           extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
98           rstride[n] = ret->dim[dim].stride * size;
99           sstride[n] = array->dim[dim].stride * size;
100
101           hstride[n] = h->dim[n].stride;
102           if (bound)
103             bstride[n] = bound->dim[n].stride;
104           else
105             bstride[n] = 0;
106           n++;
107         }
108     }
109   if (sstride[0] == 0)
110     sstride[0] = size;
111   if (rstride[0] == 0)
112     rstride[0] = size;
113   if (hstride[0] == 0)
114     hstride[0] = 1;
115   if (bound && bstride[0] == 0)
116     bstride[0] = size;
117
118   dim = GFC_DESCRIPTOR_RANK (array);
119   rstride0 = rstride[0];
120   sstride0 = sstride[0];
121   hstride0 = hstride[0];
122   bstride0 = bstride[0];
123   rptr = ret->data;
124   sptr = array->data;
125   hptr = h->data;
126   if (bound)
127     bptr = bound->data;
128   else
129     bptr = zeros;
130
131   while (rptr)
132     {
133 `      /* Do the shift for this dimension.  */'
134       sh = *hptr;
135       delta = (sh >= 0) ? sh: -sh;
136       if (sh > 0)
137         {
138           src = &sptr[delta * soffset];
139           dest = rptr;
140         }
141       else
142         {
143           src = sptr;
144           dest = &rptr[delta * roffset];
145         }
146       for (n = 0; n < len - delta; n++)
147         {
148           memcpy (dest, src, size);
149           dest += roffset;
150           src += soffset;
151         }
152       if (sh < 0)
153         dest = rptr;
154       n = delta;
155
156       while (n--)
157         {
158           memcpy (dest, bptr, size);
159           dest += roffset;
160         }
161
162       /* Advance to the next section.  */
163       rptr += rstride0;
164       sptr += sstride0;
165       hptr += hstride0;
166       bptr += bstride0;
167       count[0]++;
168       n = 0;
169       while (count[n] == extent[n])
170         {
171           /* When we get to the end of a dimension, reset it and increment
172              the next dimension.  */
173           count[n] = 0;
174           /* We could precalculate these products, but this is a less
175              frequently used path so proabably not worth it.  */
176           rptr -= rstride[n] * extent[n];
177           sptr -= sstride[n] * extent[n];
178           hptr -= hstride[n] * extent[n];
179           bptr -= bstride[n] * extent[n];
180           n++;
181           if (n >= dim - 1)
182             {
183               /* Break out of the loop.  */
184               rptr = NULL;
185               break;
186             }
187           else
188             {
189               count[n]++;
190               rptr += rstride[n];
191               sptr += sstride[n];
192               hptr += hstride[n];
193               bptr += bstride[n];
194             }
195         }
196     }
197 }
198