diff options
Diffstat (limited to 'gcc/fortran/simplify.c')
-rw-r--r-- | gcc/fortran/simplify.c | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index f0fdfbd..124558e 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -5553,20 +5553,6 @@ gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q, gfc_expr *rdx) gfc_expr * -gfc_simplify_ieee_selected_real_kind (gfc_expr *expr) -{ - gfc_actual_arglist *arg = expr->value.function.actual; - gfc_expr *p = arg->expr, *q = arg->next->expr, - *rdx = arg->next->next->expr; - - /* Currently, if IEEE is supported and this module is built, it means - all our floating-point types conform to IEEE. Hence, we simply handle - IEEE_SELECTED_REAL_KIND like SELECTED_REAL_KIND. */ - return gfc_simplify_selected_real_kind (p, q, rdx); -} - - -gfc_expr * gfc_simplify_set_exponent (gfc_expr *x, gfc_expr *i) { gfc_expr *result; @@ -6955,3 +6941,62 @@ gfc_simplify_compiler_version (void) return gfc_get_character_expr (gfc_default_character_kind, &gfc_current_locus, buffer, len); } + +/* Simplification routines for intrinsics of IEEE modules. */ + +gfc_expr * +simplify_ieee_selected_real_kind (gfc_expr *expr) +{ + gfc_actual_arglist *arg = expr->value.function.actual; + gfc_expr *p = arg->expr, *q = arg->next->expr, + *rdx = arg->next->next->expr; + + /* Currently, if IEEE is supported and this module is built, it means + all our floating-point types conform to IEEE. Hence, we simply handle + IEEE_SELECTED_REAL_KIND like SELECTED_REAL_KIND. */ + return gfc_simplify_selected_real_kind (p, q, rdx); +} + +gfc_expr * +simplify_ieee_support (gfc_expr *expr) +{ + /* We consider that if the IEEE modules are loaded, we have full support + for flags, halting and rounding, which are the three functions + (IEEE_SUPPORT_{FLAG,HALTING,ROUNDING}) allowed in constant + expressions. One day, we will need libgfortran to detect support and + communicate it back to us, allowing for partial support. */ + + return gfc_get_logical_expr (gfc_default_logical_kind, &expr->where, + true); +} + +bool +matches_ieee_function_name (gfc_symbol *sym, const char *name) +{ + int n = strlen(name); + + if (!strncmp(sym->name, name, n)) + return true; + + /* If a generic was used and renamed, we need more work to find out. + Compare the specific name. */ + if (sym->generic && !strncmp(sym->generic->sym->name, name, n)) + return true; + + return false; +} + +gfc_expr * +gfc_simplify_ieee_functions (gfc_expr *expr) +{ + gfc_symbol* sym = expr->symtree->n.sym; + + if (matches_ieee_function_name(sym, "ieee_selected_real_kind")) + return simplify_ieee_selected_real_kind (expr); + else if (matches_ieee_function_name(sym, "ieee_support_flag") + || matches_ieee_function_name(sym, "ieee_support_halting") + || matches_ieee_function_name(sym, "ieee_support_rounding")) + return simplify_ieee_support (expr); + else + return NULL; +} |