aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/trans.c
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2014-08-01 11:22:39 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2014-08-01 11:22:39 +0200
commit2422831252036d2821984173a7a22aac5518ef5c (patch)
tree782a77c0def56618c442f8f456b1bf1a0de3729c /gcc/ada/gcc-interface/trans.c
parentd77cfab2813d0921344f74c219ec3e4a173aa3f1 (diff)
downloadgcc-2422831252036d2821984173a7a22aac5518ef5c.zip
gcc-2422831252036d2821984173a7a22aac5518ef5c.tar.gz
gcc-2422831252036d2821984173a7a22aac5518ef5c.tar.bz2
[multiple changes]
2014-08-01 Arnaud Charlet <charlet@adacore.com> * ug_words, xgnatugn.adb, gcc-interface/Make-lang.in: Remove xgnatugn.adb and ug_words. 2014-08-01 Eric Botcazou <ebotcazou@adacore.com> * exp_attr.adb (Expand_N_Attribute_Reference): Check whether expansion can be avoid for Machine, Model and Rounding. (Is_Inline_Floating_Point_Attribute): Return true for Machine & Model, as well as Rounding if wrapped in a conversion to an integer type. * sem_res.adb (Simplify_Type_Conversion): Deal with Rounding as well. * gcc-interface/gigi.h (fp_arith_may_widen): Declare. * gcc-interface/utils.c (fp_arith_may_widen): New global variable. * gcc-interface/misc.c (enumerate_modes): Compute it. * gcc-interface/trans.c (FP_ARITH_MAY_WIDEN): Delete. (lvalue_required_for_attribute_p): Deal with Descriptor_Size, Machine and Model. (Attribute_to_gnu) <Attr_Model>: New case. <Attr_Machine>): Likewise. (convert_with_check): Test fp_arith_may_widen variable. 2014-08-01 Pascal Obry <obry@adacore.com> * adaint.h (GNAT_FOPEN): New definition for Windows. (GNAT_OPEN): Likewise. (GNAT_STAT): Likewise. (GNAT_FSTAT): Likewise. (GNAT_LSTAT): Likewise. (GNAT_STRUCT_STAT): Likewise. * adaint.c (__gnat_stat): Fix computation of file size for Windows. 2014-08-01 Vincent Celier <celier@adacore.com> * Makefile.rtl: Minor comment update. 2014-08-01 Vincent Celier <celier@adacore.com> * Make-generated.in: Remove dependencies for vms-help. From-SVN: r213429
Diffstat (limited to 'gcc/ada/gcc-interface/trans.c')
-rw-r--r--gcc/ada/gcc-interface/trans.c72
1 files changed, 56 insertions, 16 deletions
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))