diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
commit | b9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch) | |
tree | ed3b7284ff15c802583f6409b9c71b3739642d15 /libgfortran | |
parent | 1957047ed1c94bf17cf993a2b1866965f493ba87 (diff) | |
parent | 56638b9b1853666f575928f8baf17f70e4ed3517 (diff) | |
download | gcc-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')
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; |