aboutsummaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
committerAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
commitb9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch)
treeed3b7284ff15c802583f6409b9c71b3739642d15 /libgfortran
parent1957047ed1c94bf17cf993a2b1866965f493ba87 (diff)
parent56638b9b1853666f575928f8baf17f70e4ed3517 (diff)
downloadgcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.zip
gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.gz
gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.bz2
Merge from trunk at:
commit 56638b9b1853666f575928f8baf17f70e4ed3517 Author: GCC Administrator <gccadmin@gcc.gnu.org> Date: Wed Jun 17 00:16:36 2020 +0000 Daily bump.
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog191
-rw-r--r--libgfortran/Makefile.am3
-rw-r--r--libgfortran/Makefile.in42
-rw-r--r--libgfortran/aclocal.m41
-rw-r--r--libgfortran/c99_protos.h34
-rw-r--r--libgfortran/config.h.in21
-rw-r--r--libgfortran/config/fpu-387.h59
-rwxr-xr-xlibgfortran/configure370
-rw-r--r--libgfortran/configure.ac19
-rw-r--r--libgfortran/generated/findloc0_c10.c375
-rw-r--r--libgfortran/generated/findloc1_c10.c523
-rw-r--r--libgfortran/generated/matmul_c10.c21
-rw-r--r--libgfortran/generated/matmul_c16.c21
-rw-r--r--libgfortran/generated/matmul_c4.c21
-rw-r--r--libgfortran/generated/matmul_c8.c21
-rw-r--r--libgfortran/generated/matmul_i1.c21
-rw-r--r--libgfortran/generated/matmul_i16.c21
-rw-r--r--libgfortran/generated/matmul_i2.c21
-rw-r--r--libgfortran/generated/matmul_i4.c21
-rw-r--r--libgfortran/generated/matmul_i8.c21
-rw-r--r--libgfortran/generated/matmul_r10.c21
-rw-r--r--libgfortran/generated/matmul_r16.c21
-rw-r--r--libgfortran/generated/matmul_r4.c21
-rw-r--r--libgfortran/generated/matmul_r8.c21
-rw-r--r--libgfortran/gfortran.map22
-rw-r--r--libgfortran/intrinsics/c99_functions.c77
-rw-r--r--libgfortran/intrinsics/trigd.c291
-rw-r--r--libgfortran/intrinsics/trigd.inc493
-rw-r--r--libgfortran/intrinsics/trigd_lib.inc225
-rw-r--r--libgfortran/io/async.c30
-rw-r--r--libgfortran/io/async.h45
-rw-r--r--libgfortran/io/close.c8
-rw-r--r--libgfortran/io/format.c4
-rw-r--r--libgfortran/io/transfer.c10
-rw-r--r--libgfortran/io/unit.c25
-rw-r--r--libgfortran/io/write.c8
-rw-r--r--libgfortran/io/write_float.def4
-rw-r--r--libgfortran/m4/matmul.m421
-rw-r--r--libgfortran/runtime/error.c4
39 files changed, 2922 insertions, 256 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 840642c..6f343cd 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,194 @@
+2020-06-13 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/95313
+ * io/write.c (ztoa_big): Disable -Wstringop-overflow for one
+ line.
+
+2020-06-08 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/95091
+ * io/transfer.c (finalize_transfer): Fix type in error message.
+
+2020-06-01 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR libfortran/95418
+ * config/fpu-387.h (struct fenv): Add __attribute__ ((gcc_struct)).
+
+2020-05-29 H.J. Lu <hjl.tools@gmail.com>
+
+ PR bootstrap/95413
+ * configure: Regenerated.
+
+2020-05-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR libfortran/95390
+ * 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.
+
+2020-05-28 Harald Anlauf <anlauf@gmx.de>
+
+ PR libfortran/95104
+ * io/unit.c (unlock_unit): Guard by check for NULL pointer.
+
+2020-05-26 Harald Anlauf <anlauf@gmx.de>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR libfortran/95104
+ * io/transfer.c (st_wait_async): Do not dereference NULL pointer.
+
+2020-05-26 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/95195
+ * io/transfer.c (finalize_transfer): Generate runtime error for
+ namelist input/output to unformatted file.
+
+2020-05-23 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/95191
+ * io/async.c (async_wait_id): Generate error if ID is higher
+ than the highest current ID.
+ * runtime/error.c (translate_error): Handle LIBERROR_BAD_WAIT_ID.
+
+2020-05-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * m4/matmul.m4: Don't include <config/i386/cpuinfo.h>. Use
+ __builtin_cpu_is/__builtin_cpu_supports
+ * generated/matmul_c10.c: Regenerated.
+ * generated/matmul_c16.c: Likewise.
+ * generated/matmul_c4.c: Likewise.
+ * generated/matmul_c8.c: Likewise.
+ * generated/matmul_i1.c: Likewise.
+ * generated/matmul_i16.c: Likewise.
+ * generated/matmul_i2.c: Likewise.
+ * generated/matmul_i4.c: Likewise.
+ * generated/matmul_i8.c: Likewise.
+ * generated/matmul_r10.c: Likewise.
+ * generated/matmul_r16.c: Likewise.
+ * generated/matmul_r4.c: Likewise.
+ * generated/matmul_r8.c: Likewise.
+
+2020-05-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR bootstrap/95147
+ * configure: Regenerated.
+
+2020-05-14 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/95119
+ * io/close.c (close_status): Add CLOSE_INVALID.
+ (st_close): Return early on invalid STATUS parameter.
+
+2020-05-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure: Regenerated.
+
+2020-05-06 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/fpu-387.h (__math_force_eval): Remove.
+ (__math_force_eval_div): New define.
+ (local_feraiseexcept): Use __math_force_eval_div to use
+ generic division to generate INVALID, DIVZERO and INEXACT
+ exceptions.
+ (struct fenv): Define named struct instead of typedef.
+
+2020-05-01 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/fpu-387.h (__math_force_eval): New define.
+ (local_feraiseexcept): Use __math_force_eval to evaluate
+ generic division to generate INVALID and DIVZERO exceptions.
+
+2020-04-22 Fritz Reese <foreese@gcc.gnu.org>
+
+ * intrinsics/trigd.c, intrinsics/trigd_lib.inc, intrinsics/trigd.inc:
+ Guard against unavailable math functions.
+ Use suffixes from kinds.h based on the REAL kind.
+
+2020-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR libfortran/94694
+ PR libfortran/94586
+ * configure.ac: Add math func checks for fmaf, fma and fmal. Add
+ HAVE_INLINE_BUILTIN_COPYSIGN check.
+ * c99_protos.h (copysign, fmaf, fma, fmal): Provide fallback
+ prototypes.
+ (HAVE_COPYSIGN, HAVE_FMAF, HAVE_FMA, HAVE_FMAL): Define if not
+ defined and fallback version is provided.
+ * intrinsics/c99_functions.c (copysign, fmaf, fma, fmal): Provide
+ fallback implementations if possible
+ * configure: Regenerated.
+ * config.h.in: Regenerated.
+
+2020-04-19 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/fpu-387.h (local_feraiseexcept) [__SSE_MATH__]:
+ Remove unneeded assignments to volatile memory.
+
+2020-04-01 Fritz Reese <foreese@gcc.gnu.org>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/93871
+ * Makefile.am, Makefile.in: New make rule for intrinsics/trigd.c.
+ * gfortran.map: New routines for {sind, cosd, tand}X{r4, r8, r10, r16}.
+ * intrinsics/trigd.c, intrinsics/trigd_lib.inc, intrinsics/trigd.inc:
+ New files. Defines native degree-valued trig functions.
+
+2020-02-18 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/93599
+ * io/async.c (destroy_adv_cond): Do not destroy lock.
+ (async_io): Make sure au->lock is locked for finishing of thread.
+ Do not lock/unlock around signalling emptysignal. Unlock au->lock
+ before return.
+ (init_adv_cond): Do not initialize lock.
+ (enqueue_transfer): Unlock after signal.
+ (enqueue_done_id): Likewise.
+ (enqueue_done): Likewise.
+ (enqueue_close): Likewise.
+ (enqueue_data_transfer): Likewise.
+ (async_wait_id): Do not lock/unlock around signalling au->work.
+ (async_wait): Unlock after signal.
+ * io/async.h (SIGNAL): Add comment about needed au->lock.
+ Remove locking/unlocking of advcond->lock.
+ (WAIT_SIGNAL_MUTEX): Add comment. Remove locking/unlocking of
+ advcond->lock. Unlock mutex only at the end. Loop on
+ __ghread_cond_wait returning zero.
+ (REVOKE_SIGNAL): Add comment. Remove locking/unlocking of
+ advcond->lock.
+ (struct adv_cond): Remove mutex from struct.
+
+2020-02-12 Sandra Loosemore <sandra@codesourcery.com>
+
+ PR libstdc++/79193
+ PR libstdc++/88999
+
+ * configure: Regenerated.
+
+2020-01-24 Maciej W. Rozycki <macro@wdc.com>
+
+ * configure.ac: Handle `--with-toolexeclibdir='.
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
+2020-01-17 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/93234
+ * io/unit.c (set_internal_unit): Set round and sign flags
+ correctly.
+
+2020-01-17 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/90374
+ * io/format.c (parse_format_list): Zero width not allowed with
+ FMT_D.
+ * io/write_float.def (build_float_string): Include range of
+ higher exponent values that require wider width.
+
2020-01-01 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libfortran/90374
diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
index 295a2d4..a8a2191 100644
--- a/libgfortran/Makefile.am
+++ b/libgfortran/Makefile.am
@@ -141,6 +141,7 @@ intrinsics/reshape_generic.c \
intrinsics/reshape_packed.c \
intrinsics/selected_int_kind.f90 \
intrinsics/selected_real_kind.f90 \
+intrinsics/trigd.c \
intrinsics/unpack_generic.c \
runtime/in_pack_generic.c \
runtime/in_unpack_generic.c
@@ -282,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= \
@@ -300,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 954f9fe..312a682 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -167,6 +167,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/override.m4 \
$(top_srcdir)/../config/stdint.m4 \
+ $(top_srcdir)/../config/toolexeclibdir.m4 \
$(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
$(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
$(top_srcdir)/acinclude.m4 $(top_srcdir)/../config/acx.m4 \
@@ -372,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
@@ -421,8 +422,9 @@ am__objects_58 = associated.lo abort.lo args.lo cshift0.lo eoshift0.lo \
pack_generic.lo selected_char_kind.lo size.lo \
spread_generic.lo string_intrinsics.lo rand.lo random.lo \
reshape_generic.lo reshape_packed.lo selected_int_kind.lo \
- selected_real_kind.lo unpack_generic.lo in_pack_generic.lo \
- in_unpack_generic.lo $(am__objects_56) $(am__objects_57)
+ selected_real_kind.lo trigd.lo unpack_generic.lo \
+ in_pack_generic.lo in_unpack_generic.lo $(am__objects_56) \
+ $(am__objects_57)
@IEEE_SUPPORT_TRUE@am__objects_59 = ieee_arithmetic.lo \
@IEEE_SUPPORT_TRUE@ ieee_exceptions.lo ieee_features.lo
am__objects_60 =
@@ -770,9 +772,9 @@ gfor_helper_src = intrinsics/associated.c intrinsics/abort.c \
intrinsics/rand.c intrinsics/random.c \
intrinsics/reshape_generic.c intrinsics/reshape_packed.c \
intrinsics/selected_int_kind.f90 \
- intrinsics/selected_real_kind.f90 intrinsics/unpack_generic.c \
- runtime/in_pack_generic.c runtime/in_unpack_generic.c \
- $(am__append_3) $(am__append_4)
+ intrinsics/selected_real_kind.f90 intrinsics/trigd.c \
+ intrinsics/unpack_generic.c runtime/in_pack_generic.c \
+ runtime/in_unpack_generic.c $(am__append_3) $(am__append_4)
@IEEE_SUPPORT_FALSE@gfor_ieee_src =
@IEEE_SUPPORT_TRUE@gfor_ieee_src = \
@IEEE_SUPPORT_TRUE@ieee/ieee_arithmetic.F90 \
@@ -842,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 = \
@@ -860,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 = \
@@ -1820,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@
@@ -1834,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@
@@ -2251,6 +2257,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transfer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transfer128.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trigd.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/umask.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix.Plo@am__quote@
@@ -5983,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
@@ -6081,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
@@ -6403,6 +6424,13 @@ reshape_packed.lo: intrinsics/reshape_packed.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 reshape_packed.lo `test -f 'intrinsics/reshape_packed.c' || echo '$(srcdir)/'`intrinsics/reshape_packed.c
+trigd.lo: intrinsics/trigd.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 trigd.lo -MD -MP -MF $(DEPDIR)/trigd.Tpo -c -o trigd.lo `test -f 'intrinsics/trigd.c' || echo '$(srcdir)/'`intrinsics/trigd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/trigd.Tpo $(DEPDIR)/trigd.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='intrinsics/trigd.c' object='trigd.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 trigd.lo `test -f 'intrinsics/trigd.c' || echo '$(srcdir)/'`intrinsics/trigd.c
+
unpack_generic.lo: intrinsics/unpack_generic.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 unpack_generic.lo -MD -MP -MF $(DEPDIR)/unpack_generic.Tpo -c -o unpack_generic.lo `test -f 'intrinsics/unpack_generic.c' || echo '$(srcdir)/'`intrinsics/unpack_generic.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unpack_generic.Tpo $(DEPDIR)/unpack_generic.Plo
diff --git a/libgfortran/aclocal.m4 b/libgfortran/aclocal.m4
index 7604f56..89e5496 100644
--- a/libgfortran/aclocal.m4
+++ b/libgfortran/aclocal.m4
@@ -1174,6 +1174,7 @@ m4_include([../config/lthostflags.m4])
m4_include([../config/multi.m4])
m4_include([../config/override.m4])
m4_include([../config/stdint.m4])
+m4_include([../config/toolexeclibdir.m4])
m4_include([../ltoptions.m4])
m4_include([../ltsugar.m4])
m4_include([../ltversion.m4])
diff --git a/libgfortran/c99_protos.h b/libgfortran/c99_protos.h
index 7b0bc72..1ffc645 100644
--- a/libgfortran/c99_protos.h
+++ b/libgfortran/c99_protos.h
@@ -71,6 +71,16 @@ extern float ceilf(float);
extern float copysignf(float, float);
#endif
+#if !defined(HAVE_COPYSIGN) && defined(HAVE_INLINE_BUILTIN_COPYSIGN)
+#define HAVE_COPYSIGN 1
+extern double copysign(double, double);
+#endif
+
+#if !defined(HAVE_COPYSIGNL) && defined(HAVE_INLINE_BUILTIN_COPYSIGNL)
+#define HAVE_COPYSIGNL 1
+extern long double copysignl(long double, long double);
+#endif
+
#ifndef HAVE_COSF
#define HAVE_COSF 1
extern float cosf(float);
@@ -91,6 +101,16 @@ extern float expf(float);
extern float fabsf(float);
#endif
+#if !defined(HAVE_FABS) && defined(HAVE_INLINE_BUILTIN_FABS)
+#define HAVE_FABS 1
+extern double fabs(double);
+#endif
+
+#if !defined(HAVE_FABSL) && defined(HAVE_INLINE_BUILTIN_FABSL)
+#define HAVE_FABSL 1
+extern long double fabsl(long double);
+#endif
+
#ifndef HAVE_FLOORF
#define HAVE_FLOORF 1
extern float floorf(float);
@@ -628,6 +648,20 @@ extern float tgammaf (float);
extern float lgammaf (float);
#endif
+#ifndef HAVE_FMA
+#define HAVE_FMA 1
+extern double fma(double, double, double);
+#endif
+
+#ifndef HAVE_FMAF
+#define HAVE_FMAF 1
+extern float fmaf(float, float, float);
+#endif
+
+#ifndef HAVE_FMAL
+#define HAVE_FMAL 1
+extern long double fmal(long double, long double, long double);
+#endif
#endif /* C99_PROTOS_H */
diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in
index 4478639..2d58188 100644
--- a/libgfortran/config.h.in
+++ b/libgfortran/config.h.in
@@ -381,12 +381,21 @@
/* Define to 1 if you have the `floorl' function. */
#undef HAVE_FLOORL
+/* Define to 1 if you have the `fma' function. */
+#undef HAVE_FMA
+
/* Define if FMA3 instructions can be compiled. */
#undef HAVE_FMA3
/* Define if FMA4 instructions can be compiled. */
#undef HAVE_FMA4
+/* Define to 1 if you have the `fmaf' function. */
+#undef HAVE_FMAF
+
+/* Define to 1 if you have the `fmal' function. */
+#undef HAVE_FMAL
+
/* Define to 1 if you have the `fmod' function. */
#undef HAVE_FMOD
@@ -504,6 +513,18 @@
/* Define to 1 if you have the <ieeefp.h> header file. */
#undef HAVE_IEEEFP_H
+/* Define to 1 if `__builtin_copysign' is expanded inline. */
+#undef HAVE_INLINE_BUILTIN_COPYSIGN
+
+/* Define to 1 if `__builtin_copysignl' is expanded inline. */
+#undef HAVE_INLINE_BUILTIN_COPYSIGNL
+
+/* Define to 1 if `__builtin_fabs' is expanded inline. */
+#undef HAVE_INLINE_BUILTIN_FABS
+
+/* Define to 1 if `__builtin_fabsl' is expanded inline. */
+#undef HAVE_INLINE_BUILTIN_FABSL
+
/* Define to 1 if the system has the type `intptr_t'. */
#undef HAVE_INTPTR_T
diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h
index 623e878..7ff5acd 100644
--- a/libgfortran/config/fpu-387.h
+++ b/libgfortran/config/fpu-387.h
@@ -69,7 +69,7 @@ has_sse (void)
/* This structure corresponds to the layout of the block
written by FSTENV. */
-typedef struct
+struct fenv
{
unsigned short int __control_word;
unsigned short int __unused1;
@@ -79,18 +79,29 @@ typedef struct
unsigned short int __unused3;
unsigned int __eip;
unsigned short int __cs_selector;
- unsigned short int __opcode;
+ unsigned int __opcode:11;
+ unsigned int __unused4:5;
unsigned int __data_offset;
unsigned short int __data_selector;
unsigned short int __unused5;
unsigned int __mxcsr;
-}
-my_fenv_t;
+} __attribute__ ((gcc_struct));
/* Check we can actually store the FPU state in the allocated size. */
-_Static_assert (sizeof(my_fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
+_Static_assert (sizeof(struct fenv) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
"GFC_FPE_STATE_BUFFER_SIZE is too small");
+#ifdef __SSE_MATH__
+# define __math_force_eval_div(x, y) \
+ do { \
+ __asm__ ("" : "+x" (x)); __asm__ __volatile__ ("" : : "x" (x / y)); \
+ } while (0)
+#else
+# define __math_force_eval_div(x, y) \
+ do { \
+ __asm__ ("" : "+t" (x)); __asm__ __volatile__ ("" : : "f" (x / y)); \
+ } while (0)
+#endif
/* Raise the supported floating-point exceptions from EXCEPTS. Other
bits in EXCEPTS are ignored. Code originally borrowed from
@@ -99,21 +110,15 @@ _Static_assert (sizeof(my_fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
static void
local_feraiseexcept (int excepts)
{
+ struct fenv temp;
+
if (excepts & _FPU_MASK_IM)
{
float f = 0.0f;
-#ifdef __SSE_MATH__
- volatile float r __attribute__ ((unused));
- __asm__ __volatile__ ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
- r = f; /* Needed to trigger exception. */
-#else
- __asm__ __volatile__ ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
- /* No need for fwait, exception is triggered by emitted fstp. */
-#endif
+ __math_force_eval_div (f, f);
}
if (excepts & _FPU_MASK_DM)
{
- my_fenv_t temp;
__asm__ __volatile__ ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= _FPU_MASK_DM;
__asm__ __volatile__ ("fldenv\t%0" : : "m" (temp));
@@ -122,18 +127,10 @@ local_feraiseexcept (int excepts)
if (excepts & _FPU_MASK_ZM)
{
float f = 1.0f, g = 0.0f;
-#ifdef __SSE_MATH__
- volatile float r __attribute__ ((unused));
- __asm__ __volatile__ ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
- r = f; /* Needed to trigger exception. */
-#else
- __asm__ __volatile__ ("fdivs\t%1" : "+t" (f) : "m" (g));
- /* No need for fwait, exception is triggered by emitted fstp. */
-#endif
+ __math_force_eval_div (f, g);
}
if (excepts & _FPU_MASK_OM)
{
- my_fenv_t temp;
__asm__ __volatile__ ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= _FPU_MASK_OM;
__asm__ __volatile__ ("fldenv\t%0" : : "m" (temp));
@@ -141,7 +138,6 @@ local_feraiseexcept (int excepts)
}
if (excepts & _FPU_MASK_UM)
{
- my_fenv_t temp;
__asm__ __volatile__ ("fnstenv\t%0" : "=m" (temp));
temp.__status_word |= _FPU_MASK_UM;
__asm__ __volatile__ ("fldenv\t%0" : : "m" (temp));
@@ -150,14 +146,7 @@ local_feraiseexcept (int excepts)
if (excepts & _FPU_MASK_PM)
{
float f = 1.0f, g = 3.0f;
-#ifdef __SSE_MATH__
- volatile float r __attribute__ ((unused));
- __asm__ __volatile__ ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
- r = f; /* Needed to trigger exception. */
-#else
- __asm__ __volatile__ ("fdivs\t%1" : "+t" (f) : "m" (g));
- /* No need for fwait, exception is triggered by emitted fstp. */
-#endif
+ __math_force_eval_div (f, g);
}
}
@@ -283,7 +272,7 @@ get_fpu_except_flags (void)
void
set_fpu_except_flags (int set, int clear)
{
- my_fenv_t temp;
+ struct fenv temp;
int exc_set = 0, exc_clr = 0;
/* Translate from GFC_PE_* values to _FPU_MASK_* values. */
@@ -437,7 +426,7 @@ support_fpu_rounding_mode (int mode __attribute__((unused)))
void
get_fpu_state (void *state)
{
- my_fenv_t *envp = state;
+ struct fenv *envp = state;
__asm__ __volatile__ ("fnstenv\t%0" : "=m" (*envp));
@@ -452,7 +441,7 @@ get_fpu_state (void *state)
void
set_fpu_state (void *state)
{
- my_fenv_t *envp = state;
+ struct fenv *envp = state;
/* glibc sources (sysdeps/x86_64/fpu/fesetenv.c) do something more
complex than this, but I think it suffices in our case. */
diff --git a/libgfortran/configure b/libgfortran/configure
index 307da69..195f8bb 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -809,6 +809,7 @@ enable_silent_rules
enable_maintainer_mode
enable_multilib
enable_dependency_tracking
+with_toolexeclibdir
enable_cet
enable_symvers
with_gnu_ld
@@ -1465,7 +1466,7 @@ Optional Features:
do not reject slow dependency extractors
--disable-dependency-tracking
speeds up one-time build
- --enable-cet enable Intel CET in target libraries [default=no]
+ --enable-cet enable Intel CET in target libraries [default=auto]
--disable-symvers disable symbol versioning for libgfortran
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=yes]
@@ -1480,6 +1481,9 @@ Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-build-libsubdir=DIR Directory where to find libraries for build system
+ --with-toolexeclibdir=DIR
+ install libraries built with a cross compiler within
+ DIR
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-pic try to use only PIC/non-PIC objects [default=use
both]
@@ -4038,11 +4042,11 @@ done
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
+#include <stdio.h>
int
main ()
{
-
+printf ("hello world\n");
;
return 0;
}
@@ -5173,6 +5177,22 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+
+# Check whether --with-toolexeclibdir was given.
+if test "${with_toolexeclibdir+set}" = set; then :
+ withval=$with_toolexeclibdir; case ${with_toolexeclibdir} in
+ /)
+ ;;
+ */)
+ with_toolexeclibdir=`echo $with_toolexeclibdir | sed 's,/$,,'`
+ ;;
+esac
+else
+ with_toolexeclibdir=no
+fi
+
+
+
# Calculate toolexeclibdir
# Also toolexecdir, though it's only used in toolexeclibdir
case ${version_specific_libs} in
@@ -5188,7 +5208,14 @@ case ${version_specific_libs} in
test x"$with_cross_host" != x"no"; then
# Install a library built with a cross compiler in tooldir, not libdir.
toolexecdir='$(exec_prefix)/$(target_alias)'
- toolexeclibdir='$(toolexecdir)/lib'
+ case ${with_toolexeclibdir} in
+ no)
+ toolexeclibdir='$(toolexecdir)/lib'
+ ;;
+ *)
+ toolexeclibdir=${with_toolexeclibdir}
+ ;;
+ esac
else
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
toolexeclibdir='$(libdir)'
@@ -5974,19 +6001,22 @@ if test "${enable_cet+set}" = set; then :
esac
else
- enable_cet=no
+ enable_cet=auto
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CET support" >&5
$as_echo_n "checking for CET support... " >&6; }
+# NB: Avoid nested save_CFLAGS and save_LDFLAGS.
case "$host" in
i[34567]86-*-linux* | x86_64-*-linux*)
case "$enable_cet" in
auto)
# Check if target supports multi-byte NOPs
# and if assembler supports CET insn.
+ cet_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fcf-protection"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -6010,6 +6040,7 @@ else
enable_cet=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$cet_save_CFLAGS"
;;
yes)
# Check if assembler supports CET.
@@ -12692,7 +12723,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12695 "configure"
+#line 12726 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12798,7 +12829,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12801 "configure"
+#line 12832 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -19821,6 +19852,150 @@ _ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fmaf" >&5
+$as_echo_n "checking for fmaf... " >&6; }
+if ${gcc_cv_math_func_fmaf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#ifdef HAVE_COMPLEX_H
+#include <complex.h>
+#endif
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+
+int (*ptr)() = (int (*)())fmaf;
+
+int
+main ()
+{
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcc_cv_math_func_fmaf=yes
+else
+ gcc_cv_math_func_fmaf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_math_func_fmaf" >&5
+$as_echo "$gcc_cv_math_func_fmaf" >&6; }
+ if test $gcc_cv_math_func_fmaf = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FMAF 1
+_ACEOF
+
+ fi
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fma" >&5
+$as_echo_n "checking for fma... " >&6; }
+if ${gcc_cv_math_func_fma+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#ifdef HAVE_COMPLEX_H
+#include <complex.h>
+#endif
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+
+int (*ptr)() = (int (*)())fma;
+
+int
+main ()
+{
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcc_cv_math_func_fma=yes
+else
+ gcc_cv_math_func_fma=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_math_func_fma" >&5
+$as_echo "$gcc_cv_math_func_fma" >&6; }
+ if test $gcc_cv_math_func_fma = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FMA 1
+_ACEOF
+
+ fi
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fmal" >&5
+$as_echo_n "checking for fmal... " >&6; }
+if ${gcc_cv_math_func_fmal+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#ifdef HAVE_COMPLEX_H
+#include <complex.h>
+#endif
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+
+int (*ptr)() = (int (*)())fmal;
+
+int
+main ()
+{
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcc_cv_math_func_fmal=yes
+else
+ gcc_cv_math_func_fmal=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_math_func_fmal" >&5
+$as_echo "$gcc_cv_math_func_fmal" >&6; }
+ if test $gcc_cv_math_func_fmal = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FMAL 1
+_ACEOF
+
+ fi
+
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fmodf" >&5
$as_echo_n "checking for fmodf... " >&6; }
if ${gcc_cv_math_func_fmodf+:} false; then :
@@ -25532,6 +25707,187 @@ $as_echo "#define HAVE_CLOG 1" >>confdefs.h
fi
+
+
+if test $gcc_cv_math_func_copysign = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline __builtin_copysign" >&5
+$as_echo_n "checking for inline __builtin_copysign... " >&6; }
+if ${gcc_cv_math_inline_builtin_copysign+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+double
+copysign_fallback (double x, double y)
+{
+ return __builtin_copysign (x, y);
+}
+
+int
+main ()
+{
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcc_cv_math_inline_builtin_copysign=yes
+else
+ gcc_cv_math_inline_builtin_copysign=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_math_inline_builtin_copysign" >&5
+$as_echo "$gcc_cv_math_inline_builtin_copysign" >&6; }
+ if test $gcc_cv_math_inline_builtin_copysign = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INLINE_BUILTIN_COPYSIGN 1
+_ACEOF
+
+ fi
+fi
+
+
+if test $gcc_cv_math_func_copysignl = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline __builtin_copysignl" >&5
+$as_echo_n "checking for inline __builtin_copysignl... " >&6; }
+if ${gcc_cv_math_inline_builtin_copysignl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+long double
+copysignl_fallback (long double x, long double y)
+{
+ return __builtin_copysignl (x, y);
+}
+
+int
+main ()
+{
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcc_cv_math_inline_builtin_copysignl=yes
+else
+ gcc_cv_math_inline_builtin_copysignl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_math_inline_builtin_copysignl" >&5
+$as_echo "$gcc_cv_math_inline_builtin_copysignl" >&6; }
+ if test $gcc_cv_math_inline_builtin_copysignl = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INLINE_BUILTIN_COPYSIGNL 1
+_ACEOF
+
+ fi
+fi
+
+
+if test $gcc_cv_math_func_fabs = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline __builtin_fabs" >&5
+$as_echo_n "checking for inline __builtin_fabs... " >&6; }
+if ${gcc_cv_math_inline_builtin_fabs+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+double
+fabs_fallback (double x)
+{
+ return __builtin_fabs (x);
+}
+
+int
+main ()
+{
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcc_cv_math_inline_builtin_fabs=yes
+else
+ gcc_cv_math_inline_builtin_fabs=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_math_inline_builtin_fabs" >&5
+$as_echo "$gcc_cv_math_inline_builtin_fabs" >&6; }
+ if test $gcc_cv_math_inline_builtin_fabs = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INLINE_BUILTIN_FABS 1
+_ACEOF
+
+ fi
+fi
+
+
+if test $gcc_cv_math_func_fabsl = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline __builtin_fabsl" >&5
+$as_echo_n "checking for inline __builtin_fabsl... " >&6; }
+if ${gcc_cv_math_inline_builtin_fabsl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+long double
+fabsl_fallback (long double x)
+{
+ return __builtin_fabsl (x);
+}
+
+int
+main ()
+{
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcc_cv_math_inline_builtin_fabsl=yes
+else
+ gcc_cv_math_inline_builtin_fabsl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_math_inline_builtin_fabsl" >&5
+$as_echo "$gcc_cv_math_inline_builtin_fabsl" >&6; }
+ if test $gcc_cv_math_inline_builtin_fabsl = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INLINE_BUILTIN_FABSL 1
+_ACEOF
+
+ fi
+fi
+
# Check whether the system has a working stat()
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target stat is reliable" >&5
diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index 8dcc860..711dc60 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -86,6 +86,8 @@ fi
AC_USE_SYSTEM_EXTENSIONS
+GCC_WITH_TOOLEXECLIBDIR
+
# Calculate toolexeclibdir
# Also toolexecdir, though it's only used in toolexeclibdir
case ${version_specific_libs} in
@@ -101,7 +103,14 @@ case ${version_specific_libs} in
test x"$with_cross_host" != x"no"; then
# Install a library built with a cross compiler in tooldir, not libdir.
toolexecdir='$(exec_prefix)/$(target_alias)'
- toolexeclibdir='$(toolexecdir)/lib'
+ case ${with_toolexeclibdir} in
+ no)
+ toolexeclibdir='$(toolexecdir)/lib'
+ ;;
+ *)
+ toolexeclibdir=${with_toolexeclibdir}
+ ;;
+ esac
else
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
toolexeclibdir='$(libdir)'
@@ -383,6 +392,9 @@ GCC_CHECK_MATH_FUNC([cabsl])
GCC_CHECK_MATH_FUNC([floorf])
GCC_CHECK_MATH_FUNC([floor])
GCC_CHECK_MATH_FUNC([floorl])
+GCC_CHECK_MATH_FUNC([fmaf])
+GCC_CHECK_MATH_FUNC([fma])
+GCC_CHECK_MATH_FUNC([fmal])
GCC_CHECK_MATH_FUNC([fmodf])
GCC_CHECK_MATH_FUNC([fmod])
GCC_CHECK_MATH_FUNC([fmodl])
@@ -507,6 +519,11 @@ GCC_CHECK_MATH_FUNC([catanl])
# On AIX, clog is present in libm as __clog
AC_CHECK_LIB([m],[__clog],[AC_DEFINE([HAVE_CLOG],[1],[libm includes clog])])
+GCC_CHECK_MATH_INLINE_BUILTIN_FALLBACK2([copysign], [double])
+GCC_CHECK_MATH_INLINE_BUILTIN_FALLBACK2([copysignl], [long double])
+GCC_CHECK_MATH_INLINE_BUILTIN_FALLBACK1([fabs], [double])
+GCC_CHECK_MATH_INLINE_BUILTIN_FALLBACK1([fabsl], [long double])
+
# Check whether the system has a working stat()
LIBGFOR_CHECK_WORKING_STAT
diff --git a/libgfortran/generated/findloc0_c10.c b/libgfortran/generated/findloc0_c10.c
new file mode 100644
index 0000000..0936dec
--- /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 <tk@tkoenig.net>
+
+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
+<http://www.gnu.org/licenses/>. */
+
+#include "libgfortran.h"
+#include <assert.h>
+
+#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<rank; n++)
+ dest[n * dstride] = 0 ;
+}
+
+#endif
diff --git a/libgfortran/generated/findloc1_c10.c b/libgfortran/generated/findloc1_c10.c
new file mode 100644
index 0000000..7b41b7d
--- /dev/null
+++ b/libgfortran/generated/findloc1_c10.c
@@ -0,0 +1,523 @@
+/* Implementation of the FINDLOC intrinsic
+ Copyright (C) 2018-2020 Free Software Foundation, Inc.
+ Contributed by Thomas König <tk@tkoenig.net>
+
+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
+<http://www.gnu.org/licenses/>. */
+
+#include "libgfortran.h"
+#include <assert.h>
+
+#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/generated/matmul_c10.c b/libgfortran/generated/matmul_c10.c
index e866a6a..ce5be24 100644
--- a/libgfortran/generated/matmul_c10.c
+++ b/libgfortran/generated/matmul_c10.c
@@ -2367,7 +2367,6 @@ matmul_c10_vanilla (gfc_array_c10 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_c10 (gfc_array_c10 * const restrict retarray,
gfc_array_c10 * const restrict a, gfc_array_c10 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_c10 (gfc_array_c10 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_c10_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_c10_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_c10 (gfc_array_c10 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_c10_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_c10 (gfc_array_c10 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_c10_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_c10_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_c10_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_c16.c b/libgfortran/generated/matmul_c16.c
index e6605e8..bf756d1 100644
--- a/libgfortran/generated/matmul_c16.c
+++ b/libgfortran/generated/matmul_c16.c
@@ -2367,7 +2367,6 @@ matmul_c16_vanilla (gfc_array_c16 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_c16 (gfc_array_c16 * const restrict retarray,
gfc_array_c16 * const restrict a, gfc_array_c16 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_c16 (gfc_array_c16 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_c16_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_c16_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_c16 (gfc_array_c16 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_c16_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_c16 (gfc_array_c16 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_c16_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_c16_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_c16_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_c4.c b/libgfortran/generated/matmul_c4.c
index e012fa2..5b24410 100644
--- a/libgfortran/generated/matmul_c4.c
+++ b/libgfortran/generated/matmul_c4.c
@@ -2367,7 +2367,6 @@ matmul_c4_vanilla (gfc_array_c4 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_c4 (gfc_array_c4 * const restrict retarray,
gfc_array_c4 * const restrict a, gfc_array_c4 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_c4 (gfc_array_c4 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_c4_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_c4_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_c4 (gfc_array_c4 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_c4_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_c4 (gfc_array_c4 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_c4_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_c4_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_c4_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_c8.c b/libgfortran/generated/matmul_c8.c
index 8c19b49..df3cb92 100644
--- a/libgfortran/generated/matmul_c8.c
+++ b/libgfortran/generated/matmul_c8.c
@@ -2367,7 +2367,6 @@ matmul_c8_vanilla (gfc_array_c8 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_c8 (gfc_array_c8 * const restrict retarray,
gfc_array_c8 * const restrict a, gfc_array_c8 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_c8 (gfc_array_c8 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_c8_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_c8_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_c8 (gfc_array_c8 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_c8_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_c8 (gfc_array_c8 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_c8_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_c8_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_c8_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_i1.c b/libgfortran/generated/matmul_i1.c
index 8ae4194..49b0fba 100644
--- a/libgfortran/generated/matmul_i1.c
+++ b/libgfortran/generated/matmul_i1.c
@@ -2367,7 +2367,6 @@ matmul_i1_vanilla (gfc_array_i1 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_i1 (gfc_array_i1 * const restrict retarray,
gfc_array_i1 * const restrict a, gfc_array_i1 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_i1 (gfc_array_i1 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_i1_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_i1_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_i1 (gfc_array_i1 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_i1_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_i1 (gfc_array_i1 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_i1_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_i1_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_i1_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_i16.c b/libgfortran/generated/matmul_i16.c
index cfbf920..4e1d837 100644
--- a/libgfortran/generated/matmul_i16.c
+++ b/libgfortran/generated/matmul_i16.c
@@ -2367,7 +2367,6 @@ matmul_i16_vanilla (gfc_array_i16 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_i16 (gfc_array_i16 * const restrict retarray,
gfc_array_i16 * const restrict a, gfc_array_i16 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_i16 (gfc_array_i16 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_i16_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_i16_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_i16 (gfc_array_i16 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_i16_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_i16 (gfc_array_i16 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_i16_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_i16_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_i16_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_i2.c b/libgfortran/generated/matmul_i2.c
index 5a4aeed..1912987 100644
--- a/libgfortran/generated/matmul_i2.c
+++ b/libgfortran/generated/matmul_i2.c
@@ -2367,7 +2367,6 @@ matmul_i2_vanilla (gfc_array_i2 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_i2 (gfc_array_i2 * const restrict retarray,
gfc_array_i2 * const restrict a, gfc_array_i2 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_i2 (gfc_array_i2 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_i2_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_i2_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_i2 (gfc_array_i2 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_i2_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_i2 (gfc_array_i2 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_i2_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_i2_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_i2_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_i4.c b/libgfortran/generated/matmul_i4.c
index 80592a0..ab14a0a 100644
--- a/libgfortran/generated/matmul_i4.c
+++ b/libgfortran/generated/matmul_i4.c
@@ -2367,7 +2367,6 @@ matmul_i4_vanilla (gfc_array_i4 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_i4 (gfc_array_i4 * const restrict retarray,
gfc_array_i4 * const restrict a, gfc_array_i4 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_i4 (gfc_array_i4 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_i4_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_i4_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_i4 (gfc_array_i4 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_i4_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_i4 (gfc_array_i4 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_i4_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_i4_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_i4_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_i8.c b/libgfortran/generated/matmul_i8.c
index 7e4c5bc..bc627e1 100644
--- a/libgfortran/generated/matmul_i8.c
+++ b/libgfortran/generated/matmul_i8.c
@@ -2367,7 +2367,6 @@ matmul_i8_vanilla (gfc_array_i8 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_i8 (gfc_array_i8 * const restrict retarray,
gfc_array_i8 * const restrict a, gfc_array_i8 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_i8 (gfc_array_i8 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_i8_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_i8_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_i8 (gfc_array_i8 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_i8_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_i8 (gfc_array_i8 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_i8_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_i8_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_i8_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_r10.c b/libgfortran/generated/matmul_r10.c
index d97aa41..b5e63be 100644
--- a/libgfortran/generated/matmul_r10.c
+++ b/libgfortran/generated/matmul_r10.c
@@ -2367,7 +2367,6 @@ matmul_r10_vanilla (gfc_array_r10 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_r10 (gfc_array_r10 * const restrict retarray,
gfc_array_r10 * const restrict a, gfc_array_r10 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_r10 (gfc_array_r10 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_r10_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_r10_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_r10 (gfc_array_r10 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_r10_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_r10 (gfc_array_r10 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_r10_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_r10_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_r10_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_r16.c b/libgfortran/generated/matmul_r16.c
index 82e8b50..4e6c66b 100644
--- a/libgfortran/generated/matmul_r16.c
+++ b/libgfortran/generated/matmul_r16.c
@@ -2367,7 +2367,6 @@ matmul_r16_vanilla (gfc_array_r16 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_r16 (gfc_array_r16 * const restrict retarray,
gfc_array_r16 * const restrict a, gfc_array_r16 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_r16 (gfc_array_r16 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_r16_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_r16_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_r16 (gfc_array_r16 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_r16_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_r16 (gfc_array_r16 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_r16_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_r16_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_r16_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_r4.c b/libgfortran/generated/matmul_r4.c
index 36ce7daf..202634b 100644
--- a/libgfortran/generated/matmul_r4.c
+++ b/libgfortran/generated/matmul_r4.c
@@ -2367,7 +2367,6 @@ matmul_r4_vanilla (gfc_array_r4 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_r4 (gfc_array_r4 * const restrict retarray,
gfc_array_r4 * const restrict a, gfc_array_r4 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_r4 (gfc_array_r4 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_r4_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_r4_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_r4 (gfc_array_r4 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_r4_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_r4 (gfc_array_r4 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_r4_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_r4_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_r4_avx128_fma4;
goto store;
diff --git a/libgfortran/generated/matmul_r8.c b/libgfortran/generated/matmul_r8.c
index 9a81df1..22c24e5 100644
--- a/libgfortran/generated/matmul_r8.c
+++ b/libgfortran/generated/matmul_r8.c
@@ -2367,7 +2367,6 @@ matmul_r8_vanilla (gfc_array_r8 * const restrict retarray,
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_r8 (gfc_array_r8 * const restrict retarray,
gfc_array_r8 * const restrict a, gfc_array_r8 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -2384,11 +2383,11 @@ void matmul_r8 (gfc_array_r8 * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_r8_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_r8_avx512f;
goto store;
@@ -2397,8 +2396,8 @@ void matmul_r8 (gfc_array_r8 * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_r8_avx2;
goto store;
@@ -2407,26 +2406,26 @@ void matmul_r8 (gfc_array_r8 * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_r8_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_r8_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_r8_avx128_fma4;
goto store;
diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map
index 3601bc2..f74436f 100644
--- a/libgfortran/gfortran.map
+++ b/libgfortran/gfortran.map
@@ -1606,4 +1606,26 @@ GFORTRAN_9.2 {
GFORTRAN_10 {
global:
_gfortran_os_error_at;
+ _gfortran_sind_r4;
+ _gfortran_sind_r8;
+ _gfortran_sind_r10;
+ _gfortran_sind_r16;
+ _gfortran_cosd_r4;
+ _gfortran_cosd_r8;
+ _gfortran_cosd_r10;
+ _gfortran_cosd_r16;
+ _gfortran_tand_r4;
+ _gfortran_tand_r8;
+ _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;
diff --git a/libgfortran/intrinsics/c99_functions.c b/libgfortran/intrinsics/c99_functions.c
index 3ec5aeb..b75d177 100644
--- a/libgfortran/intrinsics/c99_functions.c
+++ b/libgfortran/intrinsics/c99_functions.c
@@ -229,6 +229,17 @@ ceilf (float x)
}
#endif
+#if !defined(HAVE_COPYSIGN) && defined(HAVE_INLINE_BUILTIN_COPYSIGN)
+#define HAVE_COPYSIGN 1
+double copysign (double x, double y);
+
+double
+copysign (double x, double y)
+{
+ return __builtin_copysign (x, y);
+}
+#endif
+
#ifndef HAVE_COPYSIGNF
#define HAVE_COPYSIGNF 1
float copysignf (float x, float y);
@@ -240,6 +251,17 @@ copysignf (float x, float y)
}
#endif
+#if !defined(HAVE_COPYSIGNL) && defined(HAVE_INLINE_BUILTIN_COPYSIGNL)
+#define HAVE_COPYSIGNL 1
+long double copysignl (long double x, long double y);
+
+long double
+copysignl (long double x, long double y)
+{
+ return __builtin_copysignl (x, y);
+}
+#endif
+
#ifndef HAVE_COSF
#define HAVE_COSF 1
float cosf (float x);
@@ -273,6 +295,17 @@ expf (float x)
}
#endif
+#if !defined(HAVE_FABS) && defined(HAVE_INLINE_BUILTIN_FABS)
+#define HAVE_FABS 1
+double fabs (double x);
+
+double
+fabs (double x)
+{
+ return __builtin_fabs (x);
+}
+#endif
+
#ifndef HAVE_FABSF
#define HAVE_FABSF 1
float fabsf (float x);
@@ -284,6 +317,17 @@ fabsf (float x)
}
#endif
+#if !defined(HAVE_FABSL) && defined(HAVE_INLINE_BUILTIN_FABSL)
+#define HAVE_FABSL 1
+long double fabsl (long double x);
+
+long double
+fabsl (long double x)
+{
+ return __builtin_fabsl (x);
+}
+#endif
+
#ifndef HAVE_FLOORF
#define HAVE_FLOORF 1
float floorf (float x);
@@ -2112,3 +2156,36 @@ lgammaf (float x)
return (float) lgamma ((double) x);
}
#endif
+
+#ifndef HAVE_FMA
+#define HAVE_FMA 1
+double fma (double, double, double);
+
+double
+fma (double x, double y, double z)
+{
+ return x * y + z;
+}
+#endif
+
+#ifndef HAVE_FMAF
+#define HAVE_FMAF 1
+float fmaf (float, float, float);
+
+float
+fmaf (float x, float y, float z)
+{
+ return fma (x, y, z);
+}
+#endif
+
+#ifndef HAVE_FMAL
+#define HAVE_FMAL 1
+long double fmal (long double, long double, long double);
+
+long double
+fmal (long double x, long double y, long double z)
+{
+ return x * y + z;
+}
+#endif
diff --git a/libgfortran/intrinsics/trigd.c b/libgfortran/intrinsics/trigd.c
new file mode 100644
index 0000000..e1c51c7
--- /dev/null
+++ b/libgfortran/intrinsics/trigd.c
@@ -0,0 +1,291 @@
+/* Implementation of the degree trignometric functions COSD, SIND, TAND.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ Contributed by Steven G. Kargl <kargl@gcc.gnu.org>
+
+This file is part of the GNU Fortran 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
+<http://www.gnu.org/licenses/>. */
+
+#include "libgfortran.h"
+
+#include <math.h>
+
+/* Body of library functions which are cannot be implemented on the current
+ * platform because it lacks a capability, such as an underlying trigonometric
+ * function (sin, cos, tan) or C99 floating-point function (fabs, fmod). */
+#define STRINGIFY_EXPAND(x) #x
+#define ERROR_RETURN(f, k, x) runtime_error (#f " is unavailable for" \
+ " REAL(KIND=" STRINGIFY_EXPAND(k) ") because the system math library" \
+ " lacks support for it"); \
+ RETURN(x)
+
+/*
+ For real x, let {x}_P or x_P be the closest representible number in the
+ floating point representation which uses P binary bits of fractional
+ precision (with IEEE rounding semantics).
+
+ Similarly, let f_P(x) be shorthand for {f(x)}_P.
+
+ Let ulp_P(x) be the unit of least precision for x: in other words the
+ maximal value of |a_P - b_P| where a_P <= x <= b_P and a_P != b_P.
+
+ Let x ~= y <-> | x - y | < ulp_P(x - y).
+
+ Let deg(x) be the value of x radians in degrees.
+
+ Values for each precision P were selected as follows.
+
+
+ COSD_SMALL = 2**{-N} such that for all x <= COSD_SMALL:
+
+ * cos(deg(x)) ~= 1, or equivalently:
+
+ | 1 - cos(deg(x)) | < ulp_P(1).
+
+ Unfortunately for SIND (and therefore TAND) a similar relation is only
+ possible for REAL(4) and REAL(8). With REAL(10) and REAL(16), enough
+ precision is available such that sin_P(x) != x_P for some x less than any
+ value. (There are values where this equality holds, but the distance has
+ inflection points.)
+
+ For REAL(4) and REAL(8), we can select SIND_SMALL such that:
+
+ * sin(deg(x)) ~= deg(x), or equivalently:
+
+ | deg(x) - sin(deg(x)) | < ulp_P(deg(x)).
+
+ */
+
+#ifdef HAVE_GFC_REAL_4
+
+/* Build _gfortran_sind_r4, _gfortran_cosd_r4, and _gfortran_tand_r4 */
+
+#define KIND 4
+#define TINY 0x1.p-100 /* ~= 7.889e-31 */
+#define COSD_SMALL 0x1.p-7 /* = 7.8125e-3 */
+#define SIND_SMALL 0x1.p-5 /* = 3.125e-2 */
+#define COSD30 8.66025388e-01
+#define PIO180H 1.74560547e-02 /* high 12 bits. */
+#define PIO180L -2.76216747e-06 /* Next 24 bits. */
+
+#if defined(HAVE_FABSF) && defined(HAVE_FMODF) && defined(HAVE_COPYSIGNF)
+
+#ifdef HAVE_SINF
+#define ENABLE_SIND
+#endif
+
+#ifdef HAVE_COSF
+#define ENABLE_COSD
+#endif
+
+#ifdef HAVE_TANF
+#define ENABLE_TAND
+#endif
+
+#endif /* HAVE_FABSF && HAVE_FMODF && HAVE_COPYSIGNF */
+
+#ifdef GFC_REAL_4_INFINITY
+#define HAVE_INFINITY_KIND
+#endif
+
+#include "trigd_lib.inc"
+
+#undef KIND
+#undef TINY
+#undef COSD_SMALL
+#undef SIND_SMALL
+#undef COSD30
+#undef PIO180H
+#undef PIO180L
+#undef ENABLE_SIND
+#undef ENABLE_COSD
+#undef ENABLE_TAND
+#undef HAVE_INFINITY_KIND
+
+#endif /* HAVE_GFC_REAL_4... */
+
+
+#ifdef HAVE_GFC_REAL_8
+
+/* Build _gfortran_sind_r8, _gfortran_cosd_r8, and _gfortran_tand_r8 */
+
+#define KIND 8
+#define TINY 0x1.p-1000 /* ~= 9.33e-302 (min exp -1074) */
+#define COSD_SMALL 0x1.p-21 /* ~= 4.768e-7 */
+#define SIND_SMALL 0x1.p-19 /* ~= 9.537e-7 */
+#define COSD30 8.6602540378443860e-01
+#define PIO180H 1.7453283071517944e-02 /* high 21 bits. */
+#define PIO180L 9.4484253514332993e-09 /* Next 53 bits. */
+
+#if defined(HAVE_FABS) && defined(HAVE_FMOD) && defined(HAVE_COPYSIGN)
+
+#ifdef HAVE_SIN
+#define ENABLE_SIND
+#endif
+
+#ifdef HAVE_COS
+#define ENABLE_COSD
+#endif
+
+#ifdef HAVE_TAN
+#define ENABLE_TAND
+#endif
+
+#endif /* HAVE_FABS && HAVE_FMOD && HAVE_COPYSIGN */
+
+#ifdef GFC_REAL_8_INFINITY
+#define HAVE_INFINITY_KIND
+#endif
+
+#include "trigd_lib.inc"
+
+#undef KIND
+#undef TINY
+#undef COSD_SMALL
+#undef SIND_SMALL
+#undef COSD30
+#undef PIO180H
+#undef PIO180L
+#undef ENABLE_SIND
+#undef ENABLE_COSD
+#undef ENABLE_TAND
+#undef HAVE_INFINITY_KIND
+
+#endif /* HAVE_GFC_REAL_8... */
+
+
+#ifdef HAVE_GFC_REAL_10
+
+/* Build _gfortran_sind_r10, _gfortran_cosd_r10, and _gfortran_tand_r10 */
+
+#define KIND 10
+#define TINY 0x1.p-16400 /* ~= 1.28e-4937 (min exp -16494) */
+#define COSD_SMALL 0x1.p-26 /* ~= 1.490e-8 */
+#undef SIND_SMALL /* not precise */
+#define COSD30 8.66025403784438646787e-01
+#define PIO180H 1.74532925229868851602e-02 /* high 32 bits */
+#define PIO180L -3.04358939097084072823e-12 /* Next 64 bits */
+
+#if defined(HAVE_FABSL) && defined(HAVE_FMODL) && defined(HAVE_COPYSIGNL)
+
+#ifdef HAVE_SINL
+#define ENABLE_SIND
+#endif
+
+#ifdef HAVE_COSL
+#define ENABLE_COSD
+#endif
+
+#ifdef HAVE_TANL
+#define ENABLE_TAND
+#endif
+
+#endif /* HAVE_FABSL && HAVE_FMODL && HAVE_COPYSIGNL */
+
+#ifdef GFC_REAL_10_INFINITY
+#define HAVE_INFINITY_KIND
+#endif
+
+#include "trigd_lib.inc"
+
+#undef KIND
+#undef TINY
+#undef COSD_SMALL
+#undef SIND_SMALL
+#undef COSD30
+#undef PIO180H
+#undef PIO180L
+#undef ENABLE_SIND
+#undef ENABLE_COSD
+#undef ENABLE_TAND
+#undef HAVE_INFINITY_KIND
+
+#endif /* HAVE_GFC_REAL_10 */
+
+
+#ifdef HAVE_GFC_REAL_16
+
+/* Build _gfortran_sind_r16, _gfortran_cosd_r16, and _gfortran_tand_r16 */
+
+#define KIND 16
+#define TINY 0x1.p-16400 /* ~= 1.28e-4937 */
+#undef SIND_SMALL /* not precise */
+
+#if GFC_REAL_16_DIGITS == 64
+/* 80 bit precision, use constants from REAL(10). */
+#define COSD_SMALL 0x1.p-26 /* ~= 1.490e-8 */
+#define COSD30 8.66025403784438646787e-01
+#define PIO180H 1.74532925229868851602e-02 /* high 32 bits */
+#define PIO180L -3.04358939097084072823e-12 /* Next 64 bits */
+
+#else
+/* Proper float128 precision. */
+#define COSD_SMALL 0x1.p-51 /* ~= 4.441e-16 */
+#define COSD30 8.66025403784438646763723170752936183e-01
+#define PIO180H 1.74532925199433197605003442731685936e-02
+#define PIO180L -2.39912634365882824665106671063098954e-17
+#endif
+
+#ifdef GFC_REAL_16_IS_LONG_DOUBLE
+
+#if defined(HAVE_FABSL) && defined(HAVE_FMODL) && defined(HAVE_COPYSIGNL)
+
+#ifdef HAVE_SINL
+#define ENABLE_SIND
+#endif
+
+#ifdef HAVE_COSL
+#define ENABLE_COSD
+#endif
+
+#ifdef HAVE_TANL
+#define ENABLE_TAND
+#endif
+
+#endif /* HAVE_FABSL && HAVE_FMODL && HAVE_COPYSIGNL */
+
+#else
+
+/* libquadmath: HAVE_*Q are never defined. They must be available. */
+#define ENABLE_SIND
+#define ENABLE_COSD
+#define ENABLE_TAND
+
+#endif /* GFC_REAL_16_IS_LONG_DOUBLE */
+
+#ifdef GFC_REAL_16_INFINITY
+#define HAVE_INFINITY_KIND
+#endif
+
+#include "trigd_lib.inc"
+
+#undef KIND
+#undef TINY
+#undef COSD_SMALL
+#undef SIND_SMALL
+#undef COSD30
+#undef PIO180H
+#undef PIO180L
+#undef ENABLE_SIND
+#undef ENABLE_COSD
+#undef ENABLE_TAND
+#undef HAVE_INFINITY_KIND
+
+#endif /* HAVE_GFC_REAL_16 */
diff --git a/libgfortran/intrinsics/trigd.inc b/libgfortran/intrinsics/trigd.inc
new file mode 100644
index 0000000..ed228e8
--- /dev/null
+++ b/libgfortran/intrinsics/trigd.inc
@@ -0,0 +1,493 @@
+/* Implementation of the degree trignometric functions COSD, SIND, TAND.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ Contributed by Steven G. Kargl <kargl@gcc.gnu.org>
+ and Fritz Reese <foreese@gcc.gnu.org>
+
+This file is part of the GNU Fortran 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
+<http://www.gnu.org/licenses/>. */
+
+
+/*
+
+This file is included from both the FE and the runtime library code.
+Operations are generalized using GMP/MPFR functions. When included from
+libgfortran, these should be overridden using macros which will use native
+operations conforming to the same API. From the FE, the GMP/MPFR functions can
+be used as-is.
+
+The following macros are used and must be defined, unless listed as [optional]:
+
+FTYPE
+ Type name for the real-valued parameter.
+ Variables of this type are constructed/destroyed using mpfr_init()
+ and mpfr_clear.
+
+RETTYPE
+ Return type of the functions.
+
+RETURN(x)
+ Insert code to return a value.
+ The parameter x is the result variable, which was also the input parameter.
+
+ITYPE
+ Type name for integer types.
+
+SIND, COSD, TRIGD
+ Names for the degree-valued trig functions defined by this module.
+
+ENABLE_SIND, ENABLE_COSD, ENABLE_TAND
+ Whether the degree-valued trig functions can be enabled.
+
+ERROR_RETURN(f, k, x)
+ If ENABLE_<xxx>D is not defined, this is substituted to assert an
+ error condition for function f, kind k, and parameter x.
+ The function argument is one of {sind, cosd, tand}.
+
+ISFINITE(x)
+ Whether x is a regular number or zero (not inf or NaN).
+
+D2R(x)
+ Convert x from radians to degrees.
+
+SET_COSD30(x)
+ Set x to COSD(30), or equivalently, SIND(60).
+
+TINY_LITERAL [optional]
+ Value subtracted from 1 to cause raise INEXACT for COSD(x) for x << 1.
+ If not set, COSD(x) for x <= COSD_SMALL_LITERAL simply returns 1.
+
+COSD_SMALL_LITERAL [optional]
+ Value such that x <= COSD_SMALL_LITERAL implies COSD(x) = 1 to within the
+ precision of FTYPE. If not set, this condition is not checked.
+
+SIND_SMALL_LITERAL [optional]
+ Value such that x <= SIND_SMALL_LITERAL implies SIND(x) = D2R(x) to within
+ the precision of FTYPE. If not set, this condition is not checked.
+
+*/
+
+
+#ifdef SIND
+/* Compute sind(x) = sin(x * pi / 180). */
+
+RETTYPE
+SIND (FTYPE x)
+{
+#ifdef ENABLE_SIND
+ if (ISFINITE (x))
+ {
+ FTYPE s, one;
+
+ /* sin(-x) = - sin(x). */
+ mpfr_init (s);
+ mpfr_init_set_ui (one, 1, GFC_RND_MODE);
+ mpfr_copysign (s, one, x, GFC_RND_MODE);
+ mpfr_clear (one);
+
+#ifdef SIND_SMALL_LITERAL
+ /* sin(x) = x as x -> 0; but only for some precisions. */
+ FTYPE ax;
+ mpfr_init (ax);
+ mpfr_abs (ax, x, GFC_RND_MODE);
+ if (mpfr_cmp_ld (ax, SIND_SMALL_LITERAL) < 0)
+ {
+ D2R (x);
+ mpfr_clear (ax);
+ return x;
+ }
+
+ mpfr_swap (x, ax);
+ mpfr_clear (ax);
+
+#else
+ mpfr_abs (x, x, GFC_RND_MODE);
+#endif /* SIND_SMALL_LITERAL */
+
+ /* Reduce angle to x in [0,360]. */
+ FTYPE period;
+ mpfr_init_set_ui (period, 360, GFC_RND_MODE);
+ mpfr_fmod (x, x, period, GFC_RND_MODE);
+ mpfr_clear (period);
+
+ /* Special cases with exact results. */
+ ITYPE n;
+ mpz_init (n);
+ if (mpfr_get_z (n, x, GFC_RND_MODE) == 0 && mpz_divisible_ui_p (n, 30))
+ {
+ /* Flip sign for odd n*pi (x is % 360 so this is only for 180).
+ This respects sgn(sin(x)) = sgn(d/dx sin(x)) = sgn(cos(x)). */
+ if (mpz_divisible_ui_p (n, 180))
+ {
+ mpfr_set_ui (x, 0, GFC_RND_MODE);
+ if (mpz_cmp_ui (n, 180) == 0)
+ mpfr_neg (s, s, GFC_RND_MODE);
+ }
+ else if (mpz_divisible_ui_p (n, 90))
+ mpfr_set_si (x, (mpz_cmp_ui (n, 90) == 0 ? 1 : -1), GFC_RND_MODE);
+ else if (mpz_divisible_ui_p (n, 60))
+ {
+ SET_COSD30 (x);
+ if (mpz_cmp_ui (n, 180) >= 0)
+ mpfr_neg (x, x, GFC_RND_MODE);
+ }
+ else
+ mpfr_set_ld (x, (mpz_cmp_ui (n, 180) < 0 ? 0.5L : -0.5L),
+ GFC_RND_MODE);
+ }
+
+ /* Fold [0,360] into the range [0,45], and compute either SIN() or
+ COS() depending on symmetry of shifting into the [0,45] range. */
+ else
+ {
+ bool fold_cos = false;
+ if (mpfr_cmp_ui (x, 180) <= 0)
+ {
+ if (mpfr_cmp_ui (x, 90) <= 0)
+ {
+ if (mpfr_cmp_ui (x, 45) > 0)
+ {
+ /* x = COS(D2R(90 - x)) */
+ mpfr_ui_sub (x, 90, x, GFC_RND_MODE);
+ fold_cos = true;
+ }
+ }
+ else
+ {
+ if (mpfr_cmp_ui (x, 135) <= 0)
+ {
+ mpfr_sub_ui (x, x, 90, GFC_RND_MODE);
+ fold_cos = true;
+ }
+ else
+ mpfr_ui_sub (x, 180, x, GFC_RND_MODE);
+ }
+ }
+
+ else if (mpfr_cmp_ui (x, 270) <= 0)
+ {
+ if (mpfr_cmp_ui (x, 225) <= 0)
+ mpfr_sub_ui (x, x, 180, GFC_RND_MODE);
+ else
+ {
+ mpfr_ui_sub (x, 270, x, GFC_RND_MODE);
+ fold_cos = true;
+ }
+ mpfr_neg (s, s, GFC_RND_MODE);
+ }
+
+ else
+ {
+ if (mpfr_cmp_ui (x, 315) <= 0)
+ {
+ mpfr_sub_ui (x, x, 270, GFC_RND_MODE);
+ fold_cos = true;
+ }
+ else
+ mpfr_ui_sub (x, 360, x, GFC_RND_MODE);
+ mpfr_neg (s, s, GFC_RND_MODE);
+ }
+
+ D2R (x);
+
+ if (fold_cos)
+ mpfr_cos (x, x, GFC_RND_MODE);
+ else
+ mpfr_sin (x, x, GFC_RND_MODE);
+ }
+
+ mpfr_mul (x, x, s, GFC_RND_MODE);
+ mpz_clear (n);
+ mpfr_clear (s);
+ }
+
+ /* Return NaN for +-Inf and NaN and raise exception. */
+ else
+ mpfr_sub (x, x, x, GFC_RND_MODE);
+
+ RETURN (x);
+
+#else
+ ERROR_RETURN(sind, KIND, x);
+#endif // ENABLE_SIND
+}
+#endif // SIND
+
+
+#ifdef COSD
+/* Compute cosd(x) = cos(x * pi / 180). */
+
+RETTYPE
+COSD (FTYPE x)
+{
+#ifdef ENABLE_COSD
+#if defined(TINY_LITERAL) && defined(COSD_SMALL_LITERAL)
+ static const volatile FTYPE tiny = TINY_LITERAL;
+#endif
+
+ if (ISFINITE (x))
+ {
+#ifdef COSD_SMALL_LITERAL
+ FTYPE ax;
+ mpfr_init (ax);
+
+ mpfr_abs (ax, x, GFC_RND_MODE);
+ /* No spurious underflows!. In radians, cos(x) = 1-x*x/2 as x -> 0. */
+ if (mpfr_cmp_ld (ax, COSD_SMALL_LITERAL) <= 0)
+ {
+ mpfr_set_ui (x, 1, GFC_RND_MODE);
+#ifdef TINY_LITERAL
+ /* Cause INEXACT. */
+ if (!mpfr_zero_p (ax))
+ mpfr_sub_d (x, x, tiny, GFC_RND_MODE);
+#endif
+
+ mpfr_clear (ax);
+ return x;
+ }
+
+ mpfr_swap (x, ax);
+ mpfr_clear (ax);
+#else
+ mpfr_abs (x, x, GFC_RND_MODE);
+#endif /* COSD_SMALL_LITERAL */
+
+ /* Reduce angle to ax in [0,360]. */
+ FTYPE period;
+ mpfr_init_set_ui (period, 360, GFC_RND_MODE);
+ mpfr_fmod (x, x, period, GFC_RND_MODE);
+ mpfr_clear (period);
+
+ /* Special cases with exact results.
+ Return negative zero for cosd(270) for consistency with libm cos(). */
+ ITYPE n;
+ mpz_init (n);
+ if (mpfr_get_z (n, x, GFC_RND_MODE) == 0 && mpz_divisible_ui_p (n, 30))
+ {
+ if (mpz_divisible_ui_p (n, 180))
+ mpfr_set_si (x, (mpz_cmp_ui (n, 180) == 0 ? -1 : 1),
+ GFC_RND_MODE);
+ else if (mpz_divisible_ui_p (n, 90))
+ mpfr_set_zero (x, 0);
+ else if (mpz_divisible_ui_p (n, 60))
+ {
+ mpfr_set_ld (x, 0.5, GFC_RND_MODE);
+ if (mpz_cmp_ui (n, 60) != 0 && mpz_cmp_ui (n, 300) != 0)
+ mpfr_neg (x, x, GFC_RND_MODE);
+ }
+ else
+ {
+ SET_COSD30 (x);
+ if (mpz_cmp_ui (n, 30) != 0 && mpz_cmp_ui (n, 330) != 0)
+ mpfr_neg (x, x, GFC_RND_MODE);
+ }
+ }
+
+ /* Fold [0,360] into the range [0,45], and compute either SIN() or
+ COS() depending on symmetry of shifting into the [0,45] range. */
+ else
+ {
+ bool neg = false;
+ bool fold_sin = false;
+ if (mpfr_cmp_ui (x, 180) <= 0)
+ {
+ if (mpfr_cmp_ui (x, 90) <= 0)
+ {
+ if (mpfr_cmp_ui (x, 45) > 0)
+ {
+ mpfr_ui_sub (x, 90, x, GFC_RND_MODE);
+ fold_sin = true;
+ }
+ }
+ else
+ {
+ if (mpfr_cmp_ui (x, 135) <= 0)
+ {
+ mpfr_sub_ui (x, x, 90, GFC_RND_MODE);
+ fold_sin = true;
+ }
+ else
+ mpfr_ui_sub (x, 180, x, GFC_RND_MODE);
+ neg = true;
+ }
+ }
+
+ else if (mpfr_cmp_ui (x, 270) <= 0)
+ {
+ if (mpfr_cmp_ui (x, 225) <= 0)
+ mpfr_sub_ui (x, x, 180, GFC_RND_MODE);
+ else
+ {
+ mpfr_ui_sub (x, 270, x, GFC_RND_MODE);
+ fold_sin = true;
+ }
+ neg = true;
+ }
+
+ else
+ {
+ if (mpfr_cmp_ui (x, 315) <= 0)
+ {
+ mpfr_sub_ui (x, x, 270, GFC_RND_MODE);
+ fold_sin = true;
+ }
+ else
+ mpfr_ui_sub (x, 360, x, GFC_RND_MODE);
+ }
+
+ D2R (x);
+
+ if (fold_sin)
+ mpfr_sin (x, x, GFC_RND_MODE);
+ else
+ mpfr_cos (x, x, GFC_RND_MODE);
+
+ if (neg)
+ mpfr_neg (x, x, GFC_RND_MODE);
+ }
+
+ mpz_clear (n);
+ }
+
+ /* Return NaN for +-Inf and NaN and raise exception. */
+ else
+ mpfr_sub (x, x, x, GFC_RND_MODE);
+
+ RETURN (x);
+
+#else
+ ERROR_RETURN(cosd, KIND, x);
+#endif // ENABLE_COSD
+}
+#endif // COSD
+
+
+#ifdef TAND
+/* Compute tand(x) = tan(x * pi / 180). */
+
+RETTYPE
+TAND (FTYPE x)
+{
+#ifdef ENABLE_TAND
+ if (ISFINITE (x))
+ {
+ FTYPE s, one;
+
+ /* tan(-x) = - tan(x). */
+ mpfr_init (s);
+ mpfr_init_set_ui (one, 1, GFC_RND_MODE);
+ mpfr_copysign (s, one, x, GFC_RND_MODE);
+ mpfr_clear (one);
+
+#ifdef SIND_SMALL_LITERAL
+ /* tan(x) = x as x -> 0; but only for some precisions. */
+ FTYPE ax;
+ mpfr_init (ax);
+ mpfr_abs (ax, x, GFC_RND_MODE);
+ if (mpfr_cmp_ld (ax, SIND_SMALL_LITERAL) < 0)
+ {
+ D2R (x);
+ mpfr_clear (ax);
+ return x;
+ }
+
+ mpfr_swap (x, ax);
+ mpfr_clear (ax);
+
+#else
+ mpfr_abs (x, x, GFC_RND_MODE);
+#endif /* SIND_SMALL_LITERAL */
+
+ /* Reduce angle to x in [0,360]. */
+ FTYPE period;
+ mpfr_init_set_ui (period, 360, GFC_RND_MODE);
+ mpfr_fmod (x, x, period, GFC_RND_MODE);
+ mpfr_clear (period);
+
+ /* Special cases with exact results. */
+ ITYPE n;
+ mpz_init (n);
+ if (mpfr_get_z (n, x, GFC_RND_MODE) == 0 && mpz_divisible_ui_p (n, 45))
+ {
+ if (mpz_divisible_ui_p (n, 180))
+ mpfr_set_zero (x, 0);
+
+ /* Though mathematically NaN is more appropriate for tan(n*90),
+ returning +/-Inf offers the advantage that 1/tan(n*90) returns 0,
+ which is mathematically sound. In fact we rely on this behavior
+ to implement COTAND(x) = 1 / TAND(x).
+ */
+ else if (mpz_divisible_ui_p (n, 90))
+ mpfr_set_inf (x, mpz_cmp_ui (n, 90) == 0 ? 0 : 1);
+
+ else
+ {
+ mpfr_set_ui (x, 1, GFC_RND_MODE);
+ if (mpz_cmp_ui (n, 45) != 0 && mpz_cmp_ui (n, 225) != 0)
+ mpfr_neg (x, x, GFC_RND_MODE);
+ }
+ }
+
+ else
+ {
+ /* Fold [0,360] into the range [0,90], and compute TAN(). */
+ if (mpfr_cmp_ui (x, 180) <= 0)
+ {
+ if (mpfr_cmp_ui (x, 90) > 0)
+ {
+ mpfr_ui_sub (x, 180, x, GFC_RND_MODE);
+ mpfr_neg (s, s, GFC_RND_MODE);
+ }
+ }
+ else
+ {
+ if (mpfr_cmp_ui (x, 270) <= 0)
+ {
+ mpfr_sub_ui (x, x, 180, GFC_RND_MODE);
+ }
+ else
+ {
+ mpfr_ui_sub (x, 360, x, GFC_RND_MODE);
+ mpfr_neg (s, s, GFC_RND_MODE);
+ }
+ }
+
+ D2R (x);
+ mpfr_tan (x, x, GFC_RND_MODE);
+ }
+
+ mpfr_mul (x, x, s, GFC_RND_MODE);
+ mpz_clear (n);
+ mpfr_clear (s);
+ }
+
+ /* Return NaN for +-Inf and NaN and raise exception. */
+ else
+ mpfr_sub (x, x, x, GFC_RND_MODE);
+
+ RETURN (x);
+
+#else
+ ERROR_RETURN(tand, KIND, x);
+#endif // ENABLE_TAND
+}
+#endif // TAND
+
+/* vim: set ft=c: */
diff --git a/libgfortran/intrinsics/trigd_lib.inc b/libgfortran/intrinsics/trigd_lib.inc
new file mode 100644
index 0000000..e90f9de
--- /dev/null
+++ b/libgfortran/intrinsics/trigd_lib.inc
@@ -0,0 +1,225 @@
+/* Stub for defining degree-valued trigonometric functions in libgfortran.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ Contributed by Steven G. Kargl <kargl@gcc.gnu.org>
+ and Fritz Reese <foreese@gcc.gnu.org>
+
+This file is part of the GNU Fortran 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
+<http://www.gnu.org/licenses/>. */
+
+/*
+This replaces all GMP/MPFR functions used by trigd.inc with native versions.
+The precision is defined by FTYPE defined before including this file.
+The module which includes this file must define the following:
+
+KIND -- floating point kind (4, 8, 10, 16)
+HAVE_INFINITY_KIND -- defined iff the platform has GFC_REAL_<KIND>_INFINITY
+
+TINY [optional] -- subtract from 1 under the above condition if set
+COSD_SMALL [optional] -- for x <= COSD_SMALL, COSD(x) = 1 if set
+SIND_SMALL [optional] -- for x <= SIND_SMALL, SIND(x) = D2R(x) if set
+COSD30 -- literal value of COSD(30) to the precision of FTYPE
+PIO180H -- upper bits of pi/180 for FMA
+PIO180L -- lower bits of pi/180 for FMA
+
+ */
+
+/* FTYPE := GFC_REAL_<K> */
+#define FTYPE CONCAT_EXPAND(GFC_REAL_,KIND)
+
+/* LITERAL_SUFFIX := GFC_REAL_<K>_LITERAL_SUFFIX */
+#define LITERAL_SUFFIX CONCAT_EXPAND(FTYPE,_LITERAL_SUFFIX)
+
+/* LITERAL(X) := GFC_REAL_<K>_LITERAL(X) */
+#define LITERAL(x) CONCAT_EXPAND(x,LITERAL_SUFFIX)
+
+#define SIND CONCAT_EXPAND(sind_r, KIND)
+#define COSD CONCAT_EXPAND(cosd_r, KIND)
+#define TAND CONCAT_EXPAND(tand_r, KIND)
+
+#ifdef HAVE_INFINITY_KIND
+/* GFC_REAL_X_INFINITY */
+#define INFINITY_KIND CONCAT_EXPAND(FTYPE, _INFINITY)
+#else
+/* GFC_REAL_X_HUGE */
+#define INFINITY_KIND CONCAT_EXPAND(FTYPE, _HUGE)
+#endif
+
+#define CONCAT(x,y) x ## y
+#define CONCAT_EXPAND(x,y) CONCAT(x,y)
+
+#define COPYSIGN LITERAL(copysign)
+#define FMOD LITERAL(fmod)
+#define FABS LITERAL(fabs)
+#define FMA LITERAL(fma)
+#define SIN LITERAL(sin)
+#define COS LITERAL(cos)
+#define TAN LITERAL(tan)
+
+#ifdef TINY
+#define TINY_LITERAL LITERAL(TINY)
+#endif
+
+#ifdef COSD_SMALL
+#define COSD_SMALL_LITERAL LITERAL(COSD_SMALL)
+#endif
+
+#ifdef SIND_SMALL
+#define SIND_SMALL_LITERAL LITERAL(SIND_SMALL)
+#endif
+
+#define COSD30_LITERAL LITERAL(COSD30)
+#define PIO180H_LITERAL LITERAL(PIO180H)
+#define PIO180L_LITERAL LITERAL(PIO180L)
+
+#define ITYPE int
+#define GFC_RND_MODE 0
+#define RETTYPE FTYPE
+#define RETURN(x) return (x)
+
+#define ISFINITE(x) isfinite(x)
+#define mpfr_init(x) do { } while (0)
+#define mpfr_init_set_ui(x, v, rnd) (x = (v))
+#define mpfr_clear(x) do { } while (0)
+#define mpfr_swap(x, y) do { FTYPE z = y; y = x; x = z; } while (0)
+#define mpfr_copysign(rop, op1, op2, rnd) rop = COPYSIGN((op1), (op2))
+#define mpfr_fmod(rop, x, d, rnd) (rop = FMOD((x), (d)))
+#define mpfr_abs(rop, op, rnd) (rop = FABS(op))
+#define mpfr_cmp_ld(x, y) ((x) - (y))
+#define mpfr_cmp_ui(x, n) ((x) - (n))
+#define mpfr_zero_p(x) ((x) == 0)
+#define mpfr_set(rop, x, rnd) (rop = (x))
+#define mpfr_set_zero(rop, s) (rop = COPYSIGN(0, (s)))
+#define mpfr_set_inf(rop, s) (rop = ((s)*-2 + 1) * INFINITY_KIND)
+#define mpfr_set_ui(rop, n, rnd) (rop = (n))
+#define mpfr_set_si(rop, n, rnd) (rop = (n))
+#define mpfr_set_ld(rop, x, rnd) (rop = (x))
+#define mpfr_set_si_2exp(rop, op, exp, rnd) (rop = (0x1.p##exp))
+#define mpfr_get_z(rop, x, rnd) ((rop = (int)(x)), (rop - (x)))
+#define mpfr_mul(rop, op1, op2, rnd) (rop = ((op1) * (op2)))
+#define mpfr_sub_d(rop, op1, op2, rnd) (rop = ((op1) - (op2)))
+#define mpfr_sub_ui(rop, op1, op2, rnd) (rop = ((op1) - (op2)))
+#define mpfr_sub(rop, op1, op2, rnd) (rop = ((op1) - (op2)))
+#define mpfr_ui_sub(rop, op1, op2, rnd) (rop = ((op1) - (op2)))
+#define mpfr_neg(rop, op, rnd) (rop = -(op))
+#define mpfr_sin(rop, x, rnd) (rop = SIN(x))
+#define mpfr_cos(rop, x, rnd) (rop = COS(x))
+#define mpfr_tan(rop, x, rnd) (rop = TAN(x))
+
+#define mpz_init(n) do { } while (0)
+#define mpz_clear(x) do { } while (0)
+#define mpz_cmp_ui(x, y) ((x) - (y))
+#define mpz_divisible_ui_p(n, d) ((n) % (d) == 0)
+
+#define D2R(x) (x = FMA((x), PIO180H_LITERAL, (x) * PIO180L_LITERAL))
+
+#define SET_COSD30(x) (x = COSD30_LITERAL)
+
+#ifdef SIND
+extern FTYPE SIND (FTYPE);
+export_proto (SIND);
+#endif
+
+#ifdef COSD
+extern FTYPE COSD (FTYPE);
+export_proto (COSD);
+#endif
+
+#ifdef TAND
+extern FTYPE TAND (FTYPE);
+export_proto (TAND);
+#endif
+
+#include "trigd.inc"
+
+#undef FTYPE
+#undef LITERAL_SUFFIX
+#undef LITERAL
+#undef CONCAT3
+#undef CONCAT3_EXPAND
+#undef CONCAT
+#undef CONCAT_EXPAND
+#undef SIND
+#undef COSD
+#undef TAND
+#undef INFINITY_KIND
+
+#undef COPYSIGN
+#undef FMOD
+#undef FABS
+#undef FMA
+#undef SIN
+#undef COS
+#undef TAN
+
+#undef TINY_LITERAL
+#undef COSD_SMALL_LITERAL
+#undef SIND_SMALL_LITERAL
+#undef COSD30_LITERAL
+#undef PIO180H_LITERAL
+#undef PIO180L_LITERAL
+
+#undef ITYPE
+#undef GFC_RND_MODE
+#undef RETTYPE
+#undef RETURN
+
+#undef ISFINITE
+#undef mpfr_signbit
+
+#undef mpfr_init
+#undef mpfr_init_set_ui
+#undef mpfr_clear
+#undef mpfr_swap
+#undef mpfr_fmod
+#undef mpfr_abs
+#undef mpfr_cmp_ld
+#undef mpfr_cmp_ui
+#undef mpfr_zero_p
+#undef mpfr_set
+#undef mpfr_set_zero
+#undef mpfr_set_inf
+#undef mpfr_set_ui
+#undef mpfr_set_si
+#undef mpfr_set_ld
+#undef mpfr_set_si_2exp
+#undef mpfr_get_z
+#undef mpfr_mul_si
+#undef mpfr_sub_d
+#undef mpfr_sub_ui
+#undef mpfr_sub
+#undef mpfr_ui_sub
+#undef mpfr_neg
+#undef mpfr_sin
+#undef mpfr_cos
+#undef mpfr_tan
+
+#undef mpz_init
+#undef mpz_clear
+#undef mpz_cmp_ui
+#undef mpz_divisible_ui_p
+
+#undef FMA
+#undef D2R
+
+#undef SET_COSD30
+
+
+/* vim: set ft=c: */
diff --git a/libgfortran/io/async.c b/libgfortran/io/async.c
index ab214af..1bf38e9 100644
--- a/libgfortran/io/async.c
+++ b/libgfortran/io/async.c
@@ -80,7 +80,6 @@ update_pdt (st_parameter_dt **old, st_parameter_dt *new) {
static void
destroy_adv_cond (struct adv_cond *ac)
{
- T_ERROR (__gthread_mutex_destroy, &ac->lock);
T_ERROR (__gthread_cond_destroy, &ac->signal);
}
@@ -156,6 +155,7 @@ async_io (void *arg)
case AIO_CLOSE:
NOTE ("Received AIO_CLOSE");
+ LOCK (&au->lock);
goto finish_thread;
default:
@@ -175,7 +175,6 @@ async_io (void *arg)
else if (ctq->type == AIO_CLOSE)
{
NOTE ("Received AIO_CLOSE during error condition");
- UNLOCK (&au->lock);
goto finish_thread;
}
}
@@ -189,9 +188,7 @@ async_io (void *arg)
au->tail = NULL;
au->head = NULL;
au->empty = 1;
- UNLOCK (&au->lock);
SIGNAL (&au->emptysignal);
- LOCK (&au->lock);
}
finish_thread:
au->tail = NULL;
@@ -199,6 +196,7 @@ async_io (void *arg)
au->empty = 1;
SIGNAL (&au->emptysignal);
free (ctq);
+ UNLOCK (&au->lock);
return NULL;
}
@@ -223,7 +221,6 @@ static void
init_adv_cond (struct adv_cond *ac)
{
ac->pending = 0;
- __GTHREAD_MUTEX_INIT_FUNCTION (&ac->lock);
__GTHREAD_COND_INIT_FUNCTION (&ac->signal);
}
@@ -279,8 +276,8 @@ enqueue_transfer (async_unit *au, transfer_args *arg, enum aio_do type)
au->tail = tq;
REVOKE_SIGNAL (&(au->emptysignal));
au->empty = false;
- UNLOCK (&au->lock);
SIGNAL (&au->work);
+ UNLOCK (&au->lock);
}
/* Enqueue an st_write_done or st_read_done which contains an ID. */
@@ -303,8 +300,8 @@ enqueue_done_id (async_unit *au, enum aio_do type)
au->empty = false;
ret = au->id.high++;
NOTE ("Enqueue id: %d", ret);
- UNLOCK (&au->lock);
SIGNAL (&au->work);
+ UNLOCK (&au->lock);
return ret;
}
@@ -324,8 +321,8 @@ enqueue_done (async_unit *au, enum aio_do type)
au->tail = tq;
REVOKE_SIGNAL (&(au->emptysignal));
au->empty = false;
- UNLOCK (&au->lock);
SIGNAL (&au->work);
+ UNLOCK (&au->lock);
}
/* Enqueue a CLOSE statement. */
@@ -344,8 +341,8 @@ enqueue_close (async_unit *au)
au->tail = tq;
REVOKE_SIGNAL (&(au->emptysignal));
au->empty = false;
- UNLOCK (&au->lock);
SIGNAL (&au->work);
+ UNLOCK (&au->lock);
}
/* The asynchronous unit keeps the currently active PDT around.
@@ -374,9 +371,9 @@ enqueue_data_transfer_init (async_unit *au, st_parameter_dt *dt, int read_flag)
au->tail->next = tq;
au->tail = tq;
REVOKE_SIGNAL (&(au->emptysignal));
- au->empty = 0;
- UNLOCK (&au->lock);
+ au->empty = false;
SIGNAL (&au->work);
+ UNLOCK (&au->lock);
}
/* Collect the errors that may have happened asynchronously. Return true if
@@ -427,12 +424,17 @@ async_wait_id (st_parameter_common *cmp, async_unit *au, int i)
}
LOCK (&au->lock);
+ if (i > au->id.high)
+ {
+ generate_error_common (cmp, LIBERROR_BAD_WAIT_ID, NULL);
+ UNLOCK (&au->lock);
+ return true;
+ }
+
NOTE ("Waiting for id %d", i);
if (au->id.waiting < i)
au->id.waiting = i;
- UNLOCK (&au->lock);
SIGNAL (&(au->work));
- LOCK (&au->lock);
WAIT_SIGNAL_MUTEX (&(au->id.done),
(au->id.low >= au->id.waiting || au->empty), &au->lock);
LOCK (&au->lock);
@@ -454,8 +456,8 @@ async_wait (st_parameter_common *cmp, async_unit *au)
if (cmp == NULL)
cmp = au->error.cmp;
- SIGNAL (&(au->work));
LOCK (&(au->lock));
+ SIGNAL (&(au->work));
if (au->empty)
{
diff --git a/libgfortran/io/async.h b/libgfortran/io/async.h
index c6b2e0f..17d303c 100644
--- a/libgfortran/io/async.h
+++ b/libgfortran/io/async.h
@@ -229,44 +229,44 @@
#if ASYNC_IO
+/* au->lock has to be held when calling this macro. */
+
#define SIGNAL(advcond) do{ \
- INTERN_LOCK (&(advcond)->lock); \
(advcond)->pending = 1; \
DEBUG_PRINTF ("%s%-75s %20s():%-5d %18p\n", aio_prefix, DEBUG_ORANGE "SIGNAL: " DEBUG_NORM \
#advcond, __FUNCTION__, __LINE__, (void *) advcond); \
- T_ERROR (__gthread_cond_broadcast, &(advcond)->signal); \
- INTERN_UNLOCK (&(advcond)->lock); \
+ T_ERROR (__gthread_cond_broadcast, &(advcond)->signal); \
} while (0)
+/* Has to be entered with mutex locked. */
+
#define WAIT_SIGNAL_MUTEX(advcond, condition, mutex) do{ \
__label__ finish; \
- INTERN_LOCK (&((advcond)->lock)); \
DEBUG_PRINTF ("%s%-75s %20s():%-5d %18p\n", aio_prefix, DEBUG_BLUE "WAITING: " DEBUG_NORM \
#advcond, __FUNCTION__, __LINE__, (void *) advcond); \
- if ((advcond)->pending || (condition)){ \
- UNLOCK (mutex); \
+ if ((advcond)->pending || (condition)) \
goto finish; \
- } \
- UNLOCK (mutex); \
- while (!__gthread_cond_wait(&(advcond)->signal, &(advcond)->lock)) { \
- { int cond; \
- LOCK (mutex); cond = condition; UNLOCK (mutex); \
- if (cond){ \
- DEBUG_PRINTF ("%s%-75s %20s():%-5d %18p\n", aio_prefix, DEBUG_ORANGE "REC: " DEBUG_NORM \
- #advcond, __FUNCTION__, __LINE__, (void *)advcond); \
- break; \
- } \
+ while (1) \
+ { \
+ int err_ret = __gthread_cond_wait(&(advcond)->signal, mutex); \
+ if (err_ret) internal_error (NULL, "WAIT_SIGNAL_MUTEX failed"); \
+ if (condition) \
+ { \
+ DEBUG_PRINTF ("%s%-75s %20s():%-5d %18p\n", aio_prefix, DEBUG_ORANGE \
+ "REC: " DEBUG_NORM \
+ #advcond, __FUNCTION__, __LINE__, (void *)advcond); \
+ break; \
+ } \
} \
- } \
finish: \
- (advcond)->pending = 0; \
- INTERN_UNLOCK (&((advcond)->lock)); \
- } while (0)
+ (advcond)->pending = 0; \
+ UNLOCK (mutex); \
+ } while (0)
+
+/* au->lock has to be held when calling this macro. */
#define REVOKE_SIGNAL(advcond) do{ \
- INTERN_LOCK (&(advcond)->lock); \
(advcond)->pending = 0; \
- INTERN_UNLOCK (&(advcond)->lock); \
} while (0)
#else
@@ -330,7 +330,6 @@ struct adv_cond
{
#if ASYNC_IO
int pending;
- __gthread_mutex_t lock;
__gthread_cond_t signal;
#endif
};
diff --git a/libgfortran/io/close.c b/libgfortran/io/close.c
index 8aaa003..17e064b 100644
--- a/libgfortran/io/close.c
+++ b/libgfortran/io/close.c
@@ -31,7 +31,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#endif
typedef enum
-{ CLOSE_DELETE, CLOSE_KEEP, CLOSE_UNSPECIFIED }
+{ CLOSE_INVALID = - 1, CLOSE_DELETE, CLOSE_KEEP, CLOSE_UNSPECIFIED }
close_status;
static const st_option status_opt[] = {
@@ -61,6 +61,12 @@ st_close (st_parameter_close *clp)
find_option (&clp->common, clp->status, clp->status_len,
status_opt, "Bad STATUS parameter in CLOSE statement");
+ if (status == CLOSE_INVALID)
+ {
+ library_end ();
+ return;
+ }
+
u = find_unit (clp->common.unit);
if (ASYNC_IO && u && u->au)
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
index b42a559..3be861f 100644
--- a/libgfortran/io/format.c
+++ b/libgfortran/io/format.c
@@ -954,7 +954,9 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
}
tail->u.real.d = fmt->value;
- /* Look for optional exponent */
+ /* Look for optional exponent, not allowed for FMT_D */
+ if (t == FMT_D)
+ break;
u = format_lex (fmt);
if (u != FMT_E)
fmt->saved_token = u;
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index b8db47d..dc18bc3 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -4123,6 +4123,14 @@ finalize_transfer (st_parameter_dt *dtp)
if ((dtp->u.p.ionml != NULL)
&& (cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0)
{
+ if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
+ {
+ generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
+ "Namelist formatting for unit connected "
+ "with FORM='UNFORMATTED'");
+ return;
+ }
+
dtp->u.p.namelist_mode = 1;
if ((cf & IOPARM_DT_NAMELIST_READ_MODE) != 0)
namelist_read (dtp);
@@ -4492,7 +4500,7 @@ void
st_wait_async (st_parameter_wait *wtp)
{
gfc_unit *u = find_unit (wtp->common.unit);
- if (ASYNC_IO && u->au)
+ if (ASYNC_IO && u && u->au)
{
if (wtp->common.flags & IOPARM_WAIT_HAS_ID)
async_wait_id (&(wtp->common), u->au, *wtp->id);
diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c
index c4e1ccb..a3b0656 100644
--- a/libgfortran/io/unit.c
+++ b/libgfortran/io/unit.c
@@ -514,12 +514,12 @@ set_internal_unit (st_parameter_dt *dtp, gfc_unit *iunit, int kind)
iunit->flags.form = FORM_FORMATTED;
iunit->flags.pad = PAD_YES;
iunit->flags.status = STATUS_UNSPECIFIED;
- iunit->flags.sign = SIGN_UNSPECIFIED;
+ iunit->flags.sign = SIGN_PROCDEFINED;
iunit->flags.decimal = DECIMAL_POINT;
iunit->flags.delim = DELIM_UNSPECIFIED;
iunit->flags.encoding = ENCODING_DEFAULT;
iunit->flags.async = ASYNC_NO;
- iunit->flags.round = ROUND_UNSPECIFIED;
+ iunit->flags.round = ROUND_PROCDEFINED;
/* Initialize the data transfer parameters. */
@@ -627,12 +627,12 @@ init_units (void)
u->flags.blank = BLANK_NULL;
u->flags.pad = PAD_YES;
u->flags.position = POSITION_ASIS;
- u->flags.sign = SIGN_UNSPECIFIED;
+ u->flags.sign = SIGN_PROCDEFINED;
u->flags.decimal = DECIMAL_POINT;
u->flags.delim = DELIM_UNSPECIFIED;
u->flags.encoding = ENCODING_DEFAULT;
u->flags.async = ASYNC_NO;
- u->flags.round = ROUND_UNSPECIFIED;
+ u->flags.round = ROUND_PROCDEFINED;
u->flags.share = SHARE_UNSPECIFIED;
u->flags.cc = CC_LIST;
@@ -658,12 +658,12 @@ init_units (void)
u->flags.status = STATUS_OLD;
u->flags.blank = BLANK_NULL;
u->flags.position = POSITION_ASIS;
- u->flags.sign = SIGN_UNSPECIFIED;
+ u->flags.sign = SIGN_PROCDEFINED;
u->flags.decimal = DECIMAL_POINT;
u->flags.delim = DELIM_UNSPECIFIED;
u->flags.encoding = ENCODING_DEFAULT;
u->flags.async = ASYNC_NO;
- u->flags.round = ROUND_UNSPECIFIED;
+ u->flags.round = ROUND_PROCDEFINED;
u->flags.share = SHARE_UNSPECIFIED;
u->flags.cc = CC_LIST;
@@ -689,11 +689,11 @@ init_units (void)
u->flags.status = STATUS_OLD;
u->flags.blank = BLANK_NULL;
u->flags.position = POSITION_ASIS;
- u->flags.sign = SIGN_UNSPECIFIED;
+ u->flags.sign = SIGN_PROCDEFINED;
u->flags.decimal = DECIMAL_POINT;
u->flags.encoding = ENCODING_DEFAULT;
u->flags.async = ASYNC_NO;
- u->flags.round = ROUND_UNSPECIFIED;
+ u->flags.round = ROUND_PROCDEFINED;
u->flags.share = SHARE_UNSPECIFIED;
u->flags.cc = CC_LIST;
@@ -767,9 +767,12 @@ close_unit_1 (gfc_unit *u, int locked)
void
unlock_unit (gfc_unit *u)
{
- NOTE ("unlock_unit = %d", u->unit_number);
- UNLOCK (&u->lock);
- NOTE ("unlock_unit done");
+ if (u)
+ {
+ NOTE ("unlock_unit = %d", u->unit_number);
+ UNLOCK (&u->lock);
+ NOTE ("unlock_unit done");
+ }
}
/* close_unit()-- Close a unit. The stream is closed, and any memory
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 9f02683..346615e 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -1178,7 +1178,15 @@ ztoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
}
}
+ /* write_z, which calls ztoa_big, is called from transfer.c,
+ formatted_transfer_scalar_write. There it is passed the kind as
+ argument, which means a maximum of 16. The buffer is large
+ enough, but the compiler does not know that, so shut up the
+ warning here. */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
*q = '\0';
+#pragma GCC diagnostic pop
if (*n == 0)
return "0";
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
index 75c7942..8a1be05 100644
--- a/libgfortran/io/write_float.def
+++ b/libgfortran/io/write_float.def
@@ -497,7 +497,9 @@ build_float_string (st_parameter_dt *dtp, const fnode *f, char *buffer,
else if (f->u.real.e == 0)
{
/* Zero width specified, no leading zeros in exponent */
- if (e > 99 || e < -99)
+ if (e > 999 || e < -999)
+ edigits = 6;
+ else if (e > 99 || e < -99)
edigits = 5;
else if (e > 9 || e < -9)
edigits = 4;
diff --git a/libgfortran/m4/matmul.m4 b/libgfortran/m4/matmul.m4
index 83f4ae6..5acecf1 100644
--- a/libgfortran/m4/matmul.m4
+++ b/libgfortran/m4/matmul.m4
@@ -134,7 +134,6 @@ internal_proto('matmul_name`);
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_'rtype_code` ('rtype` * const restrict retarray,
'rtype` * const restrict a, 'rtype` * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
@@ -151,11 +150,11 @@ void matmul_'rtype_code` ('rtype` * const restrict retarray,
if (matmul_fn == NULL)
{
matmul_fn = matmul_'rtype_code`_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_'rtype_code`_avx512f;
goto store;
@@ -164,8 +163,8 @@ void matmul_'rtype_code` ('rtype` * const restrict retarray,
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_'rtype_code`_avx2;
goto store;
@@ -174,26 +173,26 @@ void matmul_'rtype_code` ('rtype` * const restrict retarray,
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_'rtype_code`_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_'rtype_code`_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_'rtype_code`_avx128_fma4;
goto store;
diff --git a/libgfortran/runtime/error.c b/libgfortran/runtime/error.c
index 9ed5d56..ff6b852 100644
--- a/libgfortran/runtime/error.c
+++ b/libgfortran/runtime/error.c
@@ -660,6 +660,10 @@ translate_error (int code)
p = "Inquire statement identifies an internal file";
break;
+ case LIBERROR_BAD_WAIT_ID:
+ p = "Bad ID in WAIT statement";
+ break;
+
default:
p = "Unknown error code";
break;