https://gcc.gnu.org/g:ca71dbbdc1022165ed858f9938f0606e0fc8a521 commit ca71dbbdc1022165ed858f9938f0606e0fc8a521 Author: Jakub Jelinek Date: Fri May 29 19:01:50 2020 +0200 libgfortran: Export forgotten _gfortran_{,m,s}findloc{0,1}_c10 [PR95390] I have noticed we don't export these 6 symbols and thus the testcase below fails to link. 2020-05-29 Jakub Jelinek PR libfortran/95390 * gfortran.dg/findloc_8.f90: New test. * Makefile.am (i_findloc0_c): Add findloc0_i10.c. (i_findloc1_c): Add findloc1_i10.c. * gfortran.map (GFORTRAN_10.2): New symbol version, export _gfortran_{,m,s}findloc{0,1}_c10 symbols. * Makefile.in: Regenerated. * generated/findloc0_c10.c: Generated. * generated/findloc1_c10.c: Generated. Diff: --- gcc/testsuite/gfortran.dg/findloc_8.f90 | 29 ++ libgfortran/Makefile.am | 2 + libgfortran/Makefile.in | 22 +- libgfortran/generated/findloc0_c10.c | 375 +++++++++++++++++++++++ libgfortran/generated/findloc1_c10.c | 523 ++++++++++++++++++++++++++++++++ libgfortran/gfortran.map | 10 + 6 files changed, 959 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gfortran.dg/findloc_8.f90 b/gcc/testsuite/gfortran.dg/findloc_8.f90 new file mode 100644 index 00000000000..dffb36d61e5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/findloc_8.f90 @@ -0,0 +1,29 @@ +! PR libfortran/95390 +! { dg-do run { target fortran_real_10 } } + + complex(kind=10) :: a(6), b, d(2,2) + logical :: m(6), n, o(2,2) + integer :: c(1), e(2) + a = (/ 1., 2., 17., 2., 2., 6. /) + b = 17. + c = findloc (a, b) + if (c(1) /= 3) stop 1 + m = (/ .true., .false., .true., .true., .true., .true. /) + n = .true. + b = 2. + c = findloc (a, b, m) + if (c(1) /= 4) stop 2 + c = findloc (a, b, n) + if (c(1) /= 2) stop 3 + d = reshape((/ 1., 2., 2., 3. /), (/ 2, 2 /)) + e = findloc (d, b, 1) + if (e(1) /= 2 .or. e(2) /= 1) stop 4 + o = reshape((/ .true., .false., .true., .true. /), (/ 2, 2 /)) + e = findloc (d, b, 1, o) + if (e(1) /= 0 .or. e(2) /= 1) stop 5 + e = findloc (d, b, 1, n) + if (e(1) /= 2 .or. e(2) /= 1) stop 6 + n = .false. + e = findloc (d, b, 1, n) + if (e(1) /= 0 .or. e(2) /= 0) stop 7 +end diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am index 8ca0f6c290d..a8a2191acc3 100644 --- a/libgfortran/Makefile.am +++ b/libgfortran/Makefile.am @@ -283,6 +283,7 @@ $(srcdir)/generated/findloc0_r10.c \ $(srcdir)/generated/findloc0_r16.c \ $(srcdir)/generated/findloc0_c4.c \ $(srcdir)/generated/findloc0_c8.c \ +$(srcdir)/generated/findloc0_c10.c \ $(srcdir)/generated/findloc0_c16.c i_findloc0s_c= \ @@ -301,6 +302,7 @@ $(srcdir)/generated/findloc1_r10.c \ $(srcdir)/generated/findloc1_r16.c \ $(srcdir)/generated/findloc1_c4.c \ $(srcdir)/generated/findloc1_c8.c \ +$(srcdir)/generated/findloc1_c10.c \ $(srcdir)/generated/findloc1_c16.c i_findloc1s_c= \ diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in index 97a978aa80f..312a682b45d 100644 --- a/libgfortran/Makefile.in +++ b/libgfortran/Makefile.in @@ -373,12 +373,12 @@ am__objects_46 = minval1_s1.lo minval1_s4.lo am__objects_47 = findloc0_i1.lo findloc0_i2.lo findloc0_i4.lo \ findloc0_i8.lo findloc0_i16.lo findloc0_r4.lo findloc0_r8.lo \ findloc0_r10.lo findloc0_r16.lo findloc0_c4.lo findloc0_c8.lo \ - findloc0_c16.lo + findloc0_c10.lo findloc0_c16.lo am__objects_48 = findloc0_s1.lo findloc0_s4.lo am__objects_49 = findloc1_i1.lo findloc1_i2.lo findloc1_i4.lo \ findloc1_i8.lo findloc1_i16.lo findloc1_r4.lo findloc1_r8.lo \ findloc1_r10.lo findloc1_r16.lo findloc1_c4.lo findloc1_c8.lo \ - findloc1_c16.lo + findloc1_c10.lo findloc1_c16.lo am__objects_50 = findloc1_s1.lo findloc1_s4.lo am__objects_51 = findloc2_s1.lo findloc2_s4.lo am__objects_52 = ISO_Fortran_binding.lo @@ -844,6 +844,7 @@ $(srcdir)/generated/findloc0_r10.c \ $(srcdir)/generated/findloc0_r16.c \ $(srcdir)/generated/findloc0_c4.c \ $(srcdir)/generated/findloc0_c8.c \ +$(srcdir)/generated/findloc0_c10.c \ $(srcdir)/generated/findloc0_c16.c i_findloc0s_c = \ @@ -862,6 +863,7 @@ $(srcdir)/generated/findloc1_r10.c \ $(srcdir)/generated/findloc1_r16.c \ $(srcdir)/generated/findloc1_c4.c \ $(srcdir)/generated/findloc1_c8.c \ +$(srcdir)/generated/findloc1_c10.c \ $(srcdir)/generated/findloc1_c16.c i_findloc1s_c = \ @@ -1822,6 +1824,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extends_type_of.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fbuf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_pos.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_c10.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_c16.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_c4.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_c8.Plo@am__quote@ @@ -1836,6 +1839,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_r8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_s1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_s4.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_c10.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_c16.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_c4.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_c8.Plo@am__quote@ @@ -5986,6 +5990,13 @@ findloc0_c8.lo: $(srcdir)/generated/findloc0_c8.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o findloc0_c8.lo `test -f '$(srcdir)/generated/findloc0_c8.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc0_c8.c +findloc0_c10.lo: $(srcdir)/generated/findloc0_c10.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT findloc0_c10.lo -MD -MP -MF $(DEPDIR)/findloc0_c10.Tpo -c -o findloc0_c10.lo `test -f '$(srcdir)/generated/findloc0_c10.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc0_c10.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/findloc0_c10.Tpo $(DEPDIR)/findloc0_c10.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/generated/findloc0_c10.c' object='findloc0_c10.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o findloc0_c10.lo `test -f '$(srcdir)/generated/findloc0_c10.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc0_c10.c + findloc0_c16.lo: $(srcdir)/generated/findloc0_c16.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT findloc0_c16.lo -MD -MP -MF $(DEPDIR)/findloc0_c16.Tpo -c -o findloc0_c16.lo `test -f '$(srcdir)/generated/findloc0_c16.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc0_c16.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/findloc0_c16.Tpo $(DEPDIR)/findloc0_c16.Plo @@ -6084,6 +6095,13 @@ findloc1_c8.lo: $(srcdir)/generated/findloc1_c8.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o findloc1_c8.lo `test -f '$(srcdir)/generated/findloc1_c8.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc1_c8.c +findloc1_c10.lo: $(srcdir)/generated/findloc1_c10.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT findloc1_c10.lo -MD -MP -MF $(DEPDIR)/findloc1_c10.Tpo -c -o findloc1_c10.lo `test -f '$(srcdir)/generated/findloc1_c10.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc1_c10.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/findloc1_c10.Tpo $(DEPDIR)/findloc1_c10.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/generated/findloc1_c10.c' object='findloc1_c10.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o findloc1_c10.lo `test -f '$(srcdir)/generated/findloc1_c10.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc1_c10.c + findloc1_c16.lo: $(srcdir)/generated/findloc1_c16.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT findloc1_c16.lo -MD -MP -MF $(DEPDIR)/findloc1_c16.Tpo -c -o findloc1_c16.lo `test -f '$(srcdir)/generated/findloc1_c16.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc1_c16.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/findloc1_c16.Tpo $(DEPDIR)/findloc1_c16.Plo diff --git a/libgfortran/generated/findloc0_c10.c b/libgfortran/generated/findloc0_c10.c new file mode 100644 index 00000000000..0936dec54f8 --- /dev/null +++ b/libgfortran/generated/findloc0_c10.c @@ -0,0 +1,375 @@ + +/* Implementation of the FINDLOC intrinsic + Copyright (C) 2018-2020 Free Software Foundation, Inc. + Contributed by Thomas König + +This file is part of the GNU Fortran 95 runtime library (libgfortran). + +Libgfortran is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +Libgfortran is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#include "libgfortran.h" +#include + +#if defined (HAVE_GFC_COMPLEX_10) +extern void findloc0_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + GFC_LOGICAL_4); +export_proto(findloc0_c10); + +void +findloc0_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + GFC_LOGICAL_4 back) +{ + index_type count[GFC_MAX_DIMENSIONS]; + index_type extent[GFC_MAX_DIMENSIONS]; + index_type sstride[GFC_MAX_DIMENSIONS]; + index_type dstride; + const GFC_COMPLEX_10 *base; + index_type * restrict dest; + index_type rank; + index_type n; + index_type sz; + + rank = GFC_DESCRIPTOR_RANK (array); + if (rank <= 0) + runtime_error ("Rank of array needs to be > 0"); + + if (retarray->base_addr == NULL) + { + GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1); + retarray->dtype.rank = 1; + retarray->offset = 0; + retarray->base_addr = xmallocarray (rank, sizeof (index_type)); + } + else + { + if (unlikely (compile_options.bounds_check)) + bounds_iforeach_return ((array_t *) retarray, (array_t *) array, + "FINDLOC"); + } + + dstride = GFC_DESCRIPTOR_STRIDE(retarray,0); + dest = retarray->base_addr; + + /* Set the return value. */ + for (n = 0; n < rank; n++) + dest[n * dstride] = 0; + + sz = 1; + for (n = 0; n < rank; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); + extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); + sz *= extent[n]; + if (extent[n] <= 0) + return; + } + + for (n = 0; n < rank; n++) + count[n] = 0; + + if (back) + { + base = array->base_addr + (sz - 1) * 1; + + while (1) + { + do + { + if (unlikely(*base == value)) + { + for (n = 0; n < rank; n++) + dest[n * dstride] = extent[n] - count[n]; + + return; + } + base -= sstride[0] * 1; + } while(++count[0] != extent[0]); + + n = 0; + do + { + /* When we get to the end of a dimension, reset it and increment + the next dimension. */ + count[n] = 0; + /* We could precalculate these products, but this is a less + frequently used path so probably not worth it. */ + base += sstride[n] * extent[n] * 1; + n++; + if (n >= rank) + return; + else + { + count[n]++; + base -= sstride[n] * 1; + } + } while (count[n] == extent[n]); + } + } + else + { + base = array->base_addr; + while (1) + { + do + { + if (unlikely(*base == value)) + { + for (n = 0; n < rank; n++) + dest[n * dstride] = count[n] + 1; + + return; + } + base += sstride[0] * 1; + } while(++count[0] != extent[0]); + + n = 0; + do + { + /* When we get to the end of a dimension, reset it and increment + the next dimension. */ + count[n] = 0; + /* We could precalculate these products, but this is a less + frequently used path so probably not worth it. */ + base -= sstride[n] * extent[n] * 1; + n++; + if (n >= rank) + return; + else + { + count[n]++; + base += sstride[n] * 1; + } + } while (count[n] == extent[n]); + } + } + return; +} + +extern void mfindloc0_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + gfc_array_l1 *const restrict, GFC_LOGICAL_4); +export_proto(mfindloc0_c10); + +void +mfindloc0_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + gfc_array_l1 *const restrict mask, GFC_LOGICAL_4 back) +{ + index_type count[GFC_MAX_DIMENSIONS]; + index_type extent[GFC_MAX_DIMENSIONS]; + index_type sstride[GFC_MAX_DIMENSIONS]; + index_type mstride[GFC_MAX_DIMENSIONS]; + index_type dstride; + const GFC_COMPLEX_10 *base; + index_type * restrict dest; + GFC_LOGICAL_1 *mbase; + index_type rank; + index_type n; + int mask_kind; + index_type sz; + + rank = GFC_DESCRIPTOR_RANK (array); + if (rank <= 0) + runtime_error ("Rank of array needs to be > 0"); + + if (retarray->base_addr == NULL) + { + GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1); + retarray->dtype.rank = 1; + retarray->offset = 0; + retarray->base_addr = xmallocarray (rank, sizeof (index_type)); + } + else + { + if (unlikely (compile_options.bounds_check)) + { + bounds_iforeach_return ((array_t *) retarray, (array_t *) array, + "FINDLOC"); + bounds_equal_extents ((array_t *) mask, (array_t *) array, + "MASK argument", "FINDLOC"); + } + } + + mask_kind = GFC_DESCRIPTOR_SIZE (mask); + + mbase = mask->base_addr; + + if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8 +#ifdef HAVE_GFC_LOGICAL_16 + || mask_kind == 16 +#endif + ) + mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind); + else + internal_error (NULL, "Funny sized logical array"); + + dstride = GFC_DESCRIPTOR_STRIDE(retarray,0); + dest = retarray->base_addr; + + /* Set the return value. */ + for (n = 0; n < rank; n++) + dest[n * dstride] = 0; + + sz = 1; + for (n = 0; n < rank; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); + mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n); + extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); + sz *= extent[n]; + if (extent[n] <= 0) + return; + } + + for (n = 0; n < rank; n++) + count[n] = 0; + + if (back) + { + base = array->base_addr + (sz - 1) * 1; + mbase = mbase + (sz - 1) * mask_kind; + while (1) + { + do + { + if (unlikely(*mbase && *base == value)) + { + for (n = 0; n < rank; n++) + dest[n * dstride] = extent[n] - count[n]; + + return; + } + base -= sstride[0] * 1; + mbase -= mstride[0]; + } while(++count[0] != extent[0]); + + n = 0; + do + { + /* When we get to the end of a dimension, reset it and increment + the next dimension. */ + count[n] = 0; + /* We could precalculate these products, but this is a less + frequently used path so probably not worth it. */ + base += sstride[n] * extent[n] * 1; + mbase -= mstride[n] * extent[n]; + n++; + if (n >= rank) + return; + else + { + count[n]++; + base -= sstride[n] * 1; + mbase += mstride[n]; + } + } while (count[n] == extent[n]); + } + } + else + { + base = array->base_addr; + while (1) + { + do + { + if (unlikely(*mbase && *base == value)) + { + for (n = 0; n < rank; n++) + dest[n * dstride] = count[n] + 1; + + return; + } + base += sstride[0] * 1; + mbase += mstride[0]; + } while(++count[0] != extent[0]); + + n = 0; + do + { + /* When we get to the end of a dimension, reset it and increment + the next dimension. */ + count[n] = 0; + /* We could precalculate these products, but this is a less + frequently used path so probably not worth it. */ + base -= sstride[n] * extent[n] * 1; + mbase -= mstride[n] * extent[n]; + n++; + if (n >= rank) + return; + else + { + count[n]++; + base += sstride[n]* 1; + mbase += mstride[n]; + } + } while (count[n] == extent[n]); + } + } + return; +} + +extern void sfindloc0_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + GFC_LOGICAL_4 *, GFC_LOGICAL_4); +export_proto(sfindloc0_c10); + +void +sfindloc0_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back) +{ + index_type rank; + index_type dstride; + index_type * restrict dest; + index_type n; + + if (mask == NULL || *mask) + { + findloc0_c10 (retarray, array, value, back); + return; + } + + rank = GFC_DESCRIPTOR_RANK (array); + + if (rank <= 0) + internal_error (NULL, "Rank of array needs to be > 0"); + + if (retarray->base_addr == NULL) + { + GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1); + retarray->dtype.rank = 1; + retarray->offset = 0; + retarray->base_addr = xmallocarray (rank, sizeof (index_type)); + } + else if (unlikely (compile_options.bounds_check)) + { + bounds_iforeach_return ((array_t *) retarray, (array_t *) array, + "FINDLOC"); + } + + dstride = GFC_DESCRIPTOR_STRIDE(retarray,0); + dest = retarray->base_addr; + for (n = 0; n + +This file is part of the GNU Fortran 95 runtime library (libgfortran). + +Libgfortran is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +Libgfortran is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#include "libgfortran.h" +#include + +#if defined (HAVE_GFC_COMPLEX_10) +extern void findloc1_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + const index_type * restrict pdim, GFC_LOGICAL_4 back); +export_proto(findloc1_c10); + +extern void +findloc1_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + const index_type * restrict pdim, GFC_LOGICAL_4 back) +{ + index_type count[GFC_MAX_DIMENSIONS]; + index_type extent[GFC_MAX_DIMENSIONS]; + index_type sstride[GFC_MAX_DIMENSIONS]; + index_type dstride[GFC_MAX_DIMENSIONS]; + const GFC_COMPLEX_10 * restrict base; + index_type * restrict dest; + index_type rank; + index_type n; + index_type len; + index_type delta; + index_type dim; + int continue_loop; + + /* Make dim zero based to avoid confusion. */ + rank = GFC_DESCRIPTOR_RANK (array) - 1; + dim = (*pdim) - 1; + + if (unlikely (dim < 0 || dim > rank)) + { + runtime_error ("Dim argument incorrect in FINDLOC intrinsic: " + "is %ld, should be between 1 and %ld", + (long int) dim + 1, (long int) rank + 1); + } + + len = GFC_DESCRIPTOR_EXTENT(array,dim); + if (len < 0) + len = 0; + delta = GFC_DESCRIPTOR_STRIDE(array,dim); + + for (n = 0; n < dim; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); + extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); + + if (extent[n] < 0) + extent[n] = 0; + } + for (n = dim; n < rank; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1); + extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1); + + if (extent[n] < 0) + extent[n] = 0; + } + + if (retarray->base_addr == NULL) + { + size_t alloc_size, str; + + for (n = 0; n < rank; n++) + { + if (n == 0) + str = 1; + else + str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1]; + + GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str); + + } + + retarray->offset = 0; + retarray->dtype.rank = rank; + + alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1]; + + retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type)); + if (alloc_size == 0) + { + /* Make sure we have a zero-sized array. */ + GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); + return; + } + } + else + { + if (rank != GFC_DESCRIPTOR_RANK (retarray)) + runtime_error ("rank of return array incorrect in" + " FINDLOC intrinsic: is %ld, should be %ld", + (long int) (GFC_DESCRIPTOR_RANK (retarray)), + (long int) rank); + + if (unlikely (compile_options.bounds_check)) + bounds_ifunction_return ((array_t *) retarray, extent, + "return value", "FINDLOC"); + } + + for (n = 0; n < rank; n++) + { + count[n] = 0; + dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n); + if (extent[n] <= 0) + return; + } + + dest = retarray->base_addr; + continue_loop = 1; + + base = array->base_addr; + while (continue_loop) + { + const GFC_COMPLEX_10 * restrict src; + index_type result; + + result = 0; + if (back) + { + src = base + (len - 1) * delta * 1; + for (n = len; n > 0; n--, src -= delta * 1) + { + if (*src == value) + { + result = n; + break; + } + } + } + else + { + src = base; + for (n = 1; n <= len; n++, src += delta * 1) + { + if (*src == value) + { + result = n; + break; + } + } + } + *dest = result; + + count[0]++; + base += sstride[0] * 1; + dest += dstride[0]; + n = 0; + while (count[n] == extent[n]) + { + count[n] = 0; + base -= sstride[n] * extent[n] * 1; + dest -= dstride[n] * extent[n]; + n++; + if (n >= rank) + { + continue_loop = 0; + break; + } + else + { + count[n]++; + base += sstride[n] * 1; + dest += dstride[n]; + } + } + } +} +extern void mfindloc1_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + const index_type * restrict pdim, gfc_array_l1 *const restrict mask, + GFC_LOGICAL_4 back); +export_proto(mfindloc1_c10); + +extern void +mfindloc1_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + const index_type * restrict pdim, gfc_array_l1 *const restrict mask, + GFC_LOGICAL_4 back) +{ + index_type count[GFC_MAX_DIMENSIONS]; + index_type extent[GFC_MAX_DIMENSIONS]; + index_type sstride[GFC_MAX_DIMENSIONS]; + index_type mstride[GFC_MAX_DIMENSIONS]; + index_type dstride[GFC_MAX_DIMENSIONS]; + const GFC_COMPLEX_10 * restrict base; + const GFC_LOGICAL_1 * restrict mbase; + index_type * restrict dest; + index_type rank; + index_type n; + index_type len; + index_type delta; + index_type mdelta; + index_type dim; + int mask_kind; + int continue_loop; + + /* Make dim zero based to avoid confusion. */ + rank = GFC_DESCRIPTOR_RANK (array) - 1; + dim = (*pdim) - 1; + + if (unlikely (dim < 0 || dim > rank)) + { + runtime_error ("Dim argument incorrect in FINDLOC intrinsic: " + "is %ld, should be between 1 and %ld", + (long int) dim + 1, (long int) rank + 1); + } + + len = GFC_DESCRIPTOR_EXTENT(array,dim); + if (len < 0) + len = 0; + + delta = GFC_DESCRIPTOR_STRIDE(array,dim); + mdelta = GFC_DESCRIPTOR_STRIDE_BYTES(mask,dim); + + mbase = mask->base_addr; + + mask_kind = GFC_DESCRIPTOR_SIZE (mask); + + if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8 +#ifdef HAVE_GFC_LOGICAL_16 + || mask_kind == 16 +#endif + ) + mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind); + else + internal_error (NULL, "Funny sized logical array"); + + for (n = 0; n < dim; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n); + mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n); + extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); + + if (extent[n] < 0) + extent[n] = 0; + } + for (n = dim; n < rank; n++) + { + sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1); + mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n + 1); + extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1); + + if (extent[n] < 0) + extent[n] = 0; + } + + if (retarray->base_addr == NULL) + { + size_t alloc_size, str; + + for (n = 0; n < rank; n++) + { + if (n == 0) + str = 1; + else + str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1]; + + GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str); + + } + + retarray->offset = 0; + retarray->dtype.rank = rank; + + alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1]; + + retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type)); + if (alloc_size == 0) + { + /* Make sure we have a zero-sized array. */ + GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); + return; + } + } + else + { + if (rank != GFC_DESCRIPTOR_RANK (retarray)) + runtime_error ("rank of return array incorrect in" + " FINDLOC intrinsic: is %ld, should be %ld", + (long int) (GFC_DESCRIPTOR_RANK (retarray)), + (long int) rank); + + if (unlikely (compile_options.bounds_check)) + bounds_ifunction_return ((array_t *) retarray, extent, + "return value", "FINDLOC"); + } + + for (n = 0; n < rank; n++) + { + count[n] = 0; + dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n); + if (extent[n] <= 0) + return; + } + + dest = retarray->base_addr; + continue_loop = 1; + + base = array->base_addr; + while (continue_loop) + { + const GFC_COMPLEX_10 * restrict src; + const GFC_LOGICAL_1 * restrict msrc; + index_type result; + + result = 0; + if (back) + { + src = base + (len - 1) * delta * 1; + msrc = mbase + (len - 1) * mdelta; + for (n = len; n > 0; n--, src -= delta * 1, msrc -= mdelta) + { + if (*msrc && *src == value) + { + result = n; + break; + } + } + } + else + { + src = base; + msrc = mbase; + for (n = 1; n <= len; n++, src += delta * 1, msrc += mdelta) + { + if (*msrc && *src == value) + { + result = n; + break; + } + } + } + *dest = result; + + count[0]++; + base += sstride[0] * 1; + mbase += mstride[0]; + dest += dstride[0]; + n = 0; + while (count[n] == extent[n]) + { + count[n] = 0; + base -= sstride[n] * extent[n] * 1; + mbase -= mstride[n] * extent[n]; + dest -= dstride[n] * extent[n]; + n++; + if (n >= rank) + { + continue_loop = 0; + break; + } + else + { + count[n]++; + base += sstride[n] * 1; + dest += dstride[n]; + } + } + } +} +extern void sfindloc1_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + const index_type * restrict pdim, GFC_LOGICAL_4 *const restrict mask, + GFC_LOGICAL_4 back); +export_proto(sfindloc1_c10); + +extern void +sfindloc1_c10 (gfc_array_index_type * const restrict retarray, + gfc_array_c10 * const restrict array, GFC_COMPLEX_10 value, + const index_type * restrict pdim, GFC_LOGICAL_4 *const restrict mask, + GFC_LOGICAL_4 back) +{ + index_type count[GFC_MAX_DIMENSIONS]; + index_type extent[GFC_MAX_DIMENSIONS]; + index_type dstride[GFC_MAX_DIMENSIONS]; + index_type * restrict dest; + index_type rank; + index_type n; + index_type len; + index_type dim; + bool continue_loop; + + if (mask == NULL || *mask) + { + findloc1_c10 (retarray, array, value, pdim, back); + return; + } + /* Make dim zero based to avoid confusion. */ + rank = GFC_DESCRIPTOR_RANK (array) - 1; + dim = (*pdim) - 1; + + if (unlikely (dim < 0 || dim > rank)) + { + runtime_error ("Dim argument incorrect in FINDLOC intrinsic: " + "is %ld, should be between 1 and %ld", + (long int) dim + 1, (long int) rank + 1); + } + + len = GFC_DESCRIPTOR_EXTENT(array,dim); + if (len < 0) + len = 0; + + for (n = 0; n < dim; n++) + { + extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); + + if (extent[n] <= 0) + extent[n] = 0; + } + + for (n = dim; n < rank; n++) + { + extent[n] = + GFC_DESCRIPTOR_EXTENT(array,n + 1); + + if (extent[n] <= 0) + extent[n] = 0; + } + + + if (retarray->base_addr == NULL) + { + size_t alloc_size, str; + + for (n = 0; n < rank; n++) + { + if (n == 0) + str = 1; + else + str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1]; + + GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str); + } + + retarray->offset = 0; + retarray->dtype.rank = rank; + + alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1]; + + retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type)); + if (alloc_size == 0) + { + /* Make sure we have a zero-sized array. */ + GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); + return; + } + } + else + { + if (rank != GFC_DESCRIPTOR_RANK (retarray)) + runtime_error ("rank of return array incorrect in" + " FINDLOC intrinsic: is %ld, should be %ld", + (long int) (GFC_DESCRIPTOR_RANK (retarray)), + (long int) rank); + + if (unlikely (compile_options.bounds_check)) + bounds_ifunction_return ((array_t *) retarray, extent, + "return value", "FINDLOC"); + } + + for (n = 0; n < rank; n++) + { + count[n] = 0; + dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n); + if (extent[n] <= 0) + return; + } + dest = retarray->base_addr; + continue_loop = 1; + + while (continue_loop) + { + *dest = 0; + + count[0]++; + dest += dstride[0]; + n = 0; + while (count[n] == extent[n]) + { + count[n] = 0; + dest -= dstride[n] * extent[n]; + n++; + if (n >= rank) + { + continue_loop = 0; + break; + } + else + { + count[n]++; + dest += dstride[n]; + } + } + } +} +#endif diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map index ebf1a6ff40b..f74436fd338 100644 --- a/libgfortran/gfortran.map +++ b/libgfortran/gfortran.map @@ -1619,3 +1619,13 @@ GFORTRAN_10 { _gfortran_tand_r10; _gfortran_tand_r16; } GFORTRAN_9.2; + +GFORTRAN_10.2 { + global: + _gfortran_findloc0_c10; + _gfortran_mfindloc0_c10; + _gfortran_sfindloc0_c10; + _gfortran_findloc1_c10; + _gfortran_mfindloc1_c10; + _gfortran_sfindloc1_c10; +} GFORTRAN_10;