aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/simplify.c
diff options
context:
space:
mode:
authorFrancois-Xavier Coudert <fxcoudert@gcc.gnu.org>2010-08-31 18:56:46 +0000
committerFrançois-Xavier Coudert <fxcoudert@gcc.gnu.org>2010-08-31 18:56:46 +0000
commitad5f4de228737897d59cb3e629f934d504029e16 (patch)
treee145f27a4197eb4dadc10cca9f891e62a370f50d /gcc/fortran/simplify.c
parent18dbb8590310fedf2948bf0677d18cddb85fa5c9 (diff)
downloadgcc-ad5f4de228737897d59cb3e629f934d504029e16.zip
gcc-ad5f4de228737897d59cb3e629f934d504029e16.tar.gz
gcc-ad5f4de228737897d59cb3e629f934d504029e16.tar.bz2
re PR fortran/38282 (Bit intrinsics: ILEN and IBCHNG)
PR fortran/38282 * f95-lang.c (gfc_init_builtin_functions): Define popcount{,l,ll} and parity{,l,ll} builtins. * trans-intrinsic.c (gfc_conv_intrinsic_popcnt_poppar): New function. (gfc_conv_intrinsic_function): Call above new functions. * simplify.c (gfc_simplify_popcnt, gfc_simplify_poppar): New functions. * intrinsic.texi: Document POPCNT and POPPAR. * gfortran.dg/popcnt_poppar_1.F90: New test. * gfortran.dg/popcnt_poppar_2.F90: New test. From-SVN: r163691
Diffstat (limited to 'gcc/fortran/simplify.c')
-rw-r--r--gcc/fortran/simplify.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 2fe7140..8649597 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -4293,6 +4293,47 @@ gfc_simplify_parity (gfc_expr *e, gfc_expr *dim)
gfc_expr *
+gfc_simplify_popcnt (gfc_expr *e)
+{
+ int res, k;
+ mpz_t x;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ k = gfc_validate_kind (e->ts.type, e->ts.kind, false);
+
+ /* Convert argument to unsigned, then count the '1' bits. */
+ mpz_init_set (x, e->value.integer);
+ convert_mpz_to_unsigned (x, gfc_integer_kinds[k].bit_size);
+ res = mpz_popcount (x);
+ mpz_clear (x);
+
+ return gfc_get_int_expr (gfc_default_integer_kind, &e->where, res);
+}
+
+
+gfc_expr *
+gfc_simplify_poppar (gfc_expr *e)
+{
+ gfc_expr *popcnt;
+ const char *s;
+ int i;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ popcnt = gfc_simplify_popcnt (e);
+ gcc_assert (popcnt);
+
+ s = gfc_extract_int (popcnt, &i);
+ gcc_assert (!s);
+
+ return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i % 2);
+}
+
+
+gfc_expr *
gfc_simplify_precision (gfc_expr *e)
{
int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);