]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/generated/norm2_r17.c
Update copyright years.
[thirdparty/gcc.git] / libgfortran / generated / norm2_r17.c
CommitLineData
49ad4d2c 1/* Implementation of the NORM2 intrinsic
a945c346 2 Copyright (C) 2010-2024 Free Software Foundation, Inc.
49ad4d2c
TK
3 Contributed by Tobias Burnus <burnus@net-b.de>
4
5This file is part of the GNU Fortran runtime library (libgfortran).
6
7Libgfortran is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public
9License as published by the Free Software Foundation; either
10version 3 of the License, or (at your option) any later version.
11
12Libgfortran is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
25
26#include "libgfortran.h"
27
28
29
30#if defined (HAVE_GFC_REAL_17) && defined (HAVE_GFC_REAL_17) && 1 /* FIXME: figure this out later. */ && 1 /* FIXME: figure this out later. */
31
32#if defined(POWER_IEEE128)
33#define MATHFUNC(funcname) __ ## funcname ## ieee128
133d0d42
JJ
34#elif defined(GFC_REAL_17_USE_IEC_60559)
35#define MATHFUNC(funcname) funcname ## f128
49ad4d2c
TK
36#else
37#define MATHFUNC(funcname) funcname ## q
38#endif
39
40
41extern void norm2_r17 (gfc_array_r17 * const restrict,
42 gfc_array_r17 * const restrict, const index_type * const restrict);
43export_proto(norm2_r17);
44
45void
46norm2_r17 (gfc_array_r17 * const restrict retarray,
47 gfc_array_r17 * 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_17 * restrict base;
55 GFC_REAL_17 * restrict dest;
56 index_type rank;
57 index_type n;
58 index_type len;
59 index_type delta;
60 index_type dim;
61 int continue_loop;
62
63 /* Make dim zero based to avoid confusion. */
64 rank = GFC_DESCRIPTOR_RANK (array) - 1;
65 dim = (*pdim) - 1;
66
67 if (unlikely (dim < 0 || dim > rank))
68 {
69 runtime_error ("Dim argument incorrect in NORM intrinsic: "
70 "is %ld, should be between 1 and %ld",
71 (long int) dim + 1, (long int) rank + 1);
72 }
73
74 len = GFC_DESCRIPTOR_EXTENT(array,dim);
75 if (len < 0)
76 len = 0;
77 delta = GFC_DESCRIPTOR_STRIDE(array,dim);
78
79 for (n = 0; n < dim; n++)
80 {
81 sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
82 extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
83
84 if (extent[n] < 0)
85 extent[n] = 0;
86 }
87 for (n = dim; n < rank; n++)
88 {
89 sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1);
90 extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
91
92 if (extent[n] < 0)
93 extent[n] = 0;
94 }
95
96 if (retarray->base_addr == NULL)
97 {
98 size_t alloc_size, str;
99
100 for (n = 0; n < rank; n++)
101 {
102 if (n == 0)
103 str = 1;
104 else
105 str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
106
107 GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
108
109 }
110
111 retarray->offset = 0;
112 retarray->dtype.rank = rank;
113
114 alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
115
116 retarray->base_addr = xmallocarray (alloc_size, sizeof (GFC_REAL_17));
117 if (alloc_size == 0)
62715bf8 118 return;
49ad4d2c
TK
119 }
120 else
121 {
122 if (rank != GFC_DESCRIPTOR_RANK (retarray))
123 runtime_error ("rank of return array incorrect in"
124 " NORM intrinsic: is %ld, should be %ld",
125 (long int) (GFC_DESCRIPTOR_RANK (retarray)),
126 (long int) rank);
127
128 if (unlikely (compile_options.bounds_check))
129 bounds_ifunction_return ((array_t *) retarray, extent,
130 "return value", "NORM");
131 }
132
133 for (n = 0; n < rank; n++)
134 {
135 count[n] = 0;
136 dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
137 if (extent[n] <= 0)
138 return;
139 }
140
141 base = array->base_addr;
142 dest = retarray->base_addr;
143
144 continue_loop = 1;
145 while (continue_loop)
146 {
147 const GFC_REAL_17 * restrict src;
148 GFC_REAL_17 result;
149 src = base;
150 {
151
152 GFC_REAL_17 scale;
153 result = 0;
154 scale = 1;
155 if (len <= 0)
156 *dest = 0;
157 else
158 {
159#if ! defined HAVE_BACK_ARG
160 for (n = 0; n < len; n++, src += delta)
161 {
162#endif
163
164 if (*src != 0)
165 {
166 GFC_REAL_17 absX, val;
167 absX = MATHFUNC(fabs) (*src);
168 if (scale < absX)
169 {
170 val = scale / absX;
171 result = 1 + result * val * val;
172 scale = absX;
173 }
174 else
175 {
176 val = absX / scale;
177 result += val * val;
178 }
179 }
180 }
181 result = scale * MATHFUNC(sqrt) (result);
182 *dest = result;
183 }
184 }
185 /* Advance to the next element. */
186 count[0]++;
187 base += sstride[0];
188 dest += dstride[0];
189 n = 0;
190 while (count[n] == extent[n])
191 {
192 /* When we get to the end of a dimension, reset it and increment
193 the next dimension. */
194 count[n] = 0;
195 /* We could precalculate these products, but this is a less
196 frequently used path so probably not worth it. */
197 base -= sstride[n] * extent[n];
198 dest -= dstride[n] * extent[n];
199 n++;
200 if (n >= rank)
201 {
202 /* Break out of the loop. */
203 continue_loop = 0;
204 break;
205 }
206 else
207 {
208 count[n]++;
209 base += sstride[n];
210 dest += dstride[n];
211 }
212 }
213 }
214}
215
216#endif