diff options
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r-- | gcc/ada/gcc-interface/Make-lang.in | 30 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/gigi.h | 3 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/misc.c | 12 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 72 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 3 |
5 files changed, 80 insertions, 40 deletions
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 4b87997..b2c6498 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -654,26 +654,7 @@ ada.tags: force # Generate documentation. -ada/doctools/xgnatugn$(build_exeext): ada/xgnatugn.adb - -$(MKDIR) ada/doctools - $(CP) $^ ada/doctools - cd ada/doctools && gnatmake -q xgnatugn - -# Note that doc/gnat_ugn.texi and doc/projects.texi do not depend on -# xgnatugn being built so we can distribute a pregenerated doc/gnat_ugn.info - -doc/gnat_ugn.texi: $(srcdir)/ada/gnat_ugn.texi $(srcdir)/ada/ug_words \ - doc/projects.texi $(gcc_docdir)/include/gcc-common.texi gcc-vers.texi - $(MAKE) ada/doctools/xgnatugn$(build_exeext) - ada/doctools/xgnatugn unw $(srcdir)/ada/gnat_ugn.texi \ - $(srcdir)/ada/ug_words doc/gnat_ugn.texi - -doc/projects.texi: $(srcdir)/ada/projects.texi - $(MAKE) ada/doctools/xgnatugn$(build_exeext) - ada/doctools/xgnatugn unw $(srcdir)/ada/projects.texi \ - $(srcdir)/ada/ug_words doc/projects.texi - -doc/gnat_ugn.info: doc/gnat_ugn.texi \ +doc/gnat_ugn.info: ada/gnat_ugn.texi ada/projects.texi \ $(gcc_docdir)/include/fdl.texi $(gcc_docdir)/include/gcc-common.texi \ gcc-vers.texi if [ x$(BUILD_INFO) = xinfo ]; then \ @@ -698,8 +679,7 @@ doc/gnat-style.info: ada/gnat-style.texi $(gcc_docdir)/include/fdl.texi \ -I$(srcdir)/ada -o $@ $<; \ else true; fi -ADA_INFOFILES = doc/gnat_ugn.info doc/gnat_ugn.texi \ - doc/gnat_rm.info doc/gnat-style.info +ADA_INFOFILES = doc/gnat_ugn.info doc/gnat_rm.info doc/gnat-style.info ada.info: $(ADA_INFOFILES) @@ -732,7 +712,8 @@ ada.html: ada.install-html: -doc/gnat_ugn.dvi: doc/gnat_ugn.texi $(gcc_docdir)/include/fdl.texi \ +doc/gnat_ugn.dvi: ada/gnat_ugn.texi ada/projects.texi \ + $(gcc_docdir)/include/fdl.texi \ $(gcc_docdir)/include/gcc-common.texi gcc-vers.texi $(TEXI2DVI) -c -I $(abs_docdir)/include -o $@ $< @@ -743,7 +724,8 @@ doc/gnat_rm.dvi: ada/gnat_rm.texi $(gcc_docdir)/include/fdl.texi \ doc/gnat-style.dvi: ada/gnat-style.texi $(gcc_docdir)/include/fdl.texi $(TEXI2DVI) -c -I $(abs_docdir)/include -o $@ $< -doc/gnat_ugn.pdf: doc/gnat_ugn.texi $(gcc_docdir)/include/fdl.texi \ +doc/gnat_ugn.pdf: ada/gnat_ugn.texi ada/projects.texi \ + $(gcc_docdir)/include/fdl.texi \ $(gcc_docdir)/include/gcc-common.texi gcc-vers.texi $(TEXI2PDF) -c -I $(abs_docdir)/include -o $@ $< diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index 15120d5..ff23863 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -335,6 +335,9 @@ extern int double_float_alignment; types whose size is greater or equal to 64 bits, or 0 if this alignment is not specifically capped. */ extern int double_scalar_alignment; + +/* True if floating-point arithmetics may use wider intermediate results. */ +extern bool fp_arith_may_widen; /* Data structures used to represent attributes. */ diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index 3d1ea17..9a07de0 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -717,6 +717,9 @@ enumerate_modes (void (*f) (const char *, int, int, int, int, int, int, int)) = { "float", "double", "long double" }; int iloop; + /* We are going to compute it below. */ + fp_arith_may_widen = false; + for (iloop = 0; iloop < NUM_MACHINE_MODES; iloop++) { enum machine_mode i = (enum machine_mode) iloop; @@ -766,6 +769,15 @@ enumerate_modes (void (*f) (const char *, int, int, int, int, int, int, int)) if (!fmt) continue; + /* Be conservative and consider that floating-point arithmetics may + use wider intermediate results as soon as there is an extended + Motorola or Intel mode supported by the machine. */ + if (fmt == &ieee_extended_motorola_format + || fmt == &ieee_extended_intel_96_format + || fmt == &ieee_extended_intel_96_round_53_format + || fmt == &ieee_extended_intel_128_format) + fp_arith_may_widen = true; + if (fmt->b == 2) digs = (fmt->p - 1) * 1233 / 4096; /* scale by log (2) */ diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 0798a66..1c26c35 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -76,18 +76,6 @@ static location_t block_end_locus_sink; #define BLOCK_SOURCE_END_LOCATION(BLOCK) block_end_locus_sink #endif -/* For efficient float-to-int rounding, it is necessary to know whether - floating-point arithmetic may use wider intermediate results. When - FP_ARITH_MAY_WIDEN is not defined, be conservative and only assume - that arithmetic does not widen if double precision is emulated. */ -#ifndef FP_ARITH_MAY_WIDEN -#if defined(HAVE_extendsfdf2) -#define FP_ARITH_MAY_WIDEN HAVE_extendsfdf2 -#else -#define FP_ARITH_MAY_WIDEN 0 -#endif -#endif - /* Pointers to front-end tables accessed through macros. */ struct Node *Nodes_Ptr; struct Flags *Flags_Ptr; @@ -804,12 +792,15 @@ lvalue_required_for_attribute_p (Node_Id gnat_node) case Attr_Object_Size: case Attr_Value_Size: case Attr_Component_Size: + case Attr_Descriptor_Size: case Attr_Max_Size_In_Storage_Elements: case Attr_Min: case Attr_Max: case Attr_Null_Parameter: case Attr_Passed_By_Reference: case Attr_Mechanism_Code: + case Attr_Machine: + case Attr_Model: return 0; case Attr_Address: @@ -2334,6 +2325,54 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) } break; + case Attr_Model: + /* We treat Model as identical to Machine. This is true for at least + IEEE and some other nice floating-point systems. */ + + /* ... fall through ... */ + + case Attr_Machine: + /* The trick is to force the compiler to store the result in memory so + that we do not have extra precision used. But do this only when this + is necessary, i.e. for a type that is not the longest floating-point + type and if FP_ARITH_MAY_WIDEN is true. */ + prefix_unused = true; + gnu_expr = gnat_to_gnu (First (Expressions (gnat_node))); + gnu_result_type = get_unpadded_type (Etype (gnat_node)); + gnu_result = convert (gnu_result_type, gnu_expr); + + if (gnu_result_type != longest_float_type_node && fp_arith_may_widen) + { + tree rec_type = make_node (RECORD_TYPE); + tree field + = create_field_decl (get_identifier ("OBJ"), gnu_result_type, + rec_type, NULL_TREE, NULL_TREE, 0, 0); + tree rec_val, asm_expr; + + finish_record_type (rec_type, field, 0, false); + + rec_val = build_constructor_single (rec_type, field, gnu_result); + rec_val = save_expr (rec_val); + + asm_expr + = build5 (ASM_EXPR, void_type_node, + build_string (0, ""), + tree_cons (build_tree_list (NULL_TREE, + build_string (2, "=m")), + rec_val, NULL_TREE), + tree_cons (build_tree_list (NULL_TREE, + build_string (1, "m")), + rec_val, NULL_TREE), + NULL_TREE, NULL_TREE); + ASM_VOLATILE_P (asm_expr) = 1; + + gnu_result + = build_compound_expr (gnu_result_type, asm_expr, + build_component_ref (rec_val, NULL_TREE, + field, false)); + } + break; + default: /* This abort means that we have an unimplemented attribute. */ gcc_unreachable (); @@ -2347,7 +2386,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) && TREE_SIDE_EFFECTS (gnu_prefix) && !Is_Entity_Name (gnat_prefix)) gnu_result - = build_compound_expr (TREE_TYPE (gnu_result), gnu_prefix, gnu_result); + = build_compound_expr (TREE_TYPE (gnu_result), gnu_prefix, gnu_result); *gnu_result_type_p = gnu_result_type; return gnu_result; @@ -8675,7 +8714,8 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflowp, /* Now convert to the result base type. If this is a non-truncating float-to-integer conversion, round. */ - if (INTEGRAL_TYPE_P (gnu_base_type) && FLOAT_TYPE_P (gnu_in_basetype) + if (INTEGRAL_TYPE_P (gnu_base_type) + && FLOAT_TYPE_P (gnu_in_basetype) && !truncatep) { REAL_VALUE_TYPE half_minus_pred_half, pred_half; @@ -8684,11 +8724,11 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflowp, const struct real_format *fmt; /* The following calculations depend on proper rounding to even - of each arithmetic operation. In order to prevent excess + of each arithmetic operation. In order to prevent excess precision from spoiling this property, use the widest hardware floating-point type if FP_ARITH_MAY_WIDEN is true. */ calc_type - = FP_ARITH_MAY_WIDEN ? longest_float_type_node : gnu_in_basetype; + = fp_arith_may_widen ? longest_float_type_node : gnu_in_basetype; /* FIXME: Should not have padding in the first place. */ if (TYPE_IS_PADDING_P (calc_type)) diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index f2afc73..b26d217 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -76,6 +76,9 @@ int double_float_alignment; is not specifically capped. */ int double_scalar_alignment; +/* True if floating-point arithmetics may use wider intermediate results. */ +bool fp_arith_may_widen = true; + /* Tree nodes for the various types and decls we create. */ tree gnat_std_decls[(int) ADT_LAST]; |