diff options
author | Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2010-08-31 18:56:46 +0000 |
---|---|---|
committer | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2010-08-31 18:56:46 +0000 |
commit | ad5f4de228737897d59cb3e629f934d504029e16 (patch) | |
tree | e145f27a4197eb4dadc10cca9f891e62a370f50d /gcc/fortran/simplify.c | |
parent | 18dbb8590310fedf2948bf0677d18cddb85fa5c9 (diff) | |
download | gcc-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.c | 41 |
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); |