gcc/libgfortran/intrinsics/trigd_lib.inc
Fritz Reese 57391ddaf3 Fix PR fortran/93871 and re-implement degree-valued trigonometric intrinsics.
2020-04-01  Fritz Reese  <foreese@gcc.gnu.org>
	    Steven G. Kargl  <kargl@gcc.gnu.org>

gcc/fortran/ChangeLog

	PR fortran/93871
	* gfortran.h (GFC_ISYM_ACOSD, GFC_ISYM_ASIND, GFC_ISYM_ATAN2D,
	GFC_ISYM_ATAND, GFC_ISYM_COSD, GFC_ISYM_COTAND, GFC_ISYM_SIND,
	GFC_ISYM_TAND): New.
	* intrinsic.c (add_functions): Remove check for flag_dec_math.
	Give degree trig functions simplification and name resolution
	functions (e.g, gfc_simplify_atrigd () and gfc_resolve_atrigd ()).
	(do_simplify): Remove special casing of degree trig functions.
	* intrinsic.h (gfc_simplify_acosd, gfc_simplify_asind,
	gfc_simplify_atand, gfc_simplify_cosd, gfc_simplify_cotand,
	gfc_simplify_sind, gfc_simplify_tand, gfc_resolve_trigd2): Add new
	prototypes.
	(gfc_simplify_atrigd, gfc_simplify_trigd, gfc_resolve_cotan,
	resolve_atrigd): Remove prototypes of deleted functions.
	* iresolve.c (is_trig_resolved, copy_replace_function_shallow,
	gfc_resolve_cotan, get_radians, get_degrees, resolve_trig_call,
	gfc_resolve_atrigd, gfc_resolve_atan2d): Delete functions.
	(gfc_resolve_trigd, gfc_resolve_trigd2): Resolve to library functions.
	* simplify.c (rad2deg, deg2rad, gfc_simplify_acosd, gfc_simplify_asind,
	gfc_simplify_atand, gfc_simplify_atan2d, gfc_simplify_cosd,
	gfc_simplify_sind, gfc_simplify_tand, gfc_simplify_cotand): New
	functions.
	(gfc_simplify_atan2): Fix error message.
	(simplify_trig_call, gfc_simplify_trigd, gfc_simplify_atrigd,
	radians_f): Delete functions.
	* trans-intrinsic.c: Add LIB_FUNCTION decls for sind, cosd, tand.
	(rad2deg, gfc_conv_intrinsic_atrigd, gfc_conv_intrinsic_cotan,
	gfc_conv_intrinsic_cotand, gfc_conv_intrinsic_atan2d): New functions.
	(gfc_conv_intrinsic_function): Handle ACOSD, ASIND, ATAND, COTAN,
	COTAND, ATAN2D.
	* trigd_fe.inc: New file. Included by simplify.c to implement
	simplify_sind, simplify_cosd, simplify_tand with code common to the
	libgfortran implementation.

gcc/testsuite/ChangeLog

	PR fortran/93871
	* gfortran.dg/dec_math.f90: Extend coverage to real(10) and real(16).
	* gfortran.dg/dec_math_2.f90: New test.
	* gfortran.dg/dec_math_3.f90: Likewise.
	* gfortran.dg/dec_math_4.f90: Likewise.
	* gfortran.dg/dec_math_5.f90: Likewise.

libgfortran/ChangeLog

	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-04-07 13:18:38 -04:00

148 lines
4.6 KiB
C

/* 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:
FTYPE -- floating point type
SIND, COSD, TAND -- names of the functions to define
SUFFIX(x) -- add a literal suffix for floating point constants (f, ...)
COSD_SMALL [optional] -- for x <= COSD_SMALL, COSD(x) = 1 if set
TINY [optional] -- subtract from 1 under the above condition 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
*/
#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 = SUFFIX(copysign)((op1), (op2))
#define mpfr_fmod(rop, x, d, rnd) (rop = SUFFIX(fmod)((x), (d)))
#define mpfr_abs(rop, op, rnd) (rop = SUFFIX(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 = SUFFIX(copysign)(0, (s)))
#define mpfr_set_inf(rop, s) (rop = ((s)*-2 + 1) * INFINITY)
#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 = SUFFIX(sin)(x))
#define mpfr_cos(rop, x, rnd) (rop = SUFFIX(cos)(x))
#define mpfr_tan(rop, x, rnd) (rop = SUFFIX(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 FMA(x,y,z) SUFFIX(fma)((x), (y), (z))
#define D2R(x) (x = FMA((x), PIO180H, (x) * PIO180L))
#define SET_COSD30(x) (x = COSD30)
extern FTYPE SIND (FTYPE);
export_proto (SIND);
extern FTYPE COSD (FTYPE);
export_proto (COSD);
extern FTYPE TAND (FTYPE);
export_proto (TAND);
#include "trigd.inc"
#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: */