diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2009-04-24 08:04:38 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2009-04-24 08:04:38 +0000 |
commit | caa9d12a2b675da20f5a3016e6f306a84ee96a2a (patch) | |
tree | 4ef92f0ee83700140ec99de85778563e3dbe29e6 /gcc/ada/gcc-interface/trans.c | |
parent | 1275de7d6eb0240c3dc56206aa68bac7a6c2318b (diff) | |
download | gcc-caa9d12a2b675da20f5a3016e6f306a84ee96a2a.zip gcc-caa9d12a2b675da20f5a3016e6f306a84ee96a2a.tar.gz gcc-caa9d12a2b675da20f5a3016e6f306a84ee96a2a.tar.bz2 |
ttypes.ads (Target_Double_Float_Alignment): New variable.
* ttypes.ads (Target_Double_Float_Alignment): New variable.
(Target_Double_Scalar_Alignment): Likewise.
* get_targ.ads (Get_Strict_Alignment): Adjust external name.
(Get_Double_Float_Alignment): New imported function.
(Get_Double_Scalar_Alignment): Likewise.
* layout.adb (Set_Elem_Alignment): Take into account specific caps for
the alignment of "double" floating-point types and "double" or larger
scalar types, as parameterized by Target_Double_Float_Alignment and
Target_Double_Scalar_Alignment respectively.
* gcc-interface/gigi.h (double_float_alignment): Declare.
(double_scalar_alignment): Likewise.
(is_double_float_or_array): Likewise.
(is_double_scalar_or_array): Likewise.
(get_target_double_float_alignment): Likewise.
(get_target_double_scalar_alignment): Likewise.
* gcc-interface/targtyps.c (get_strict_alignment): Rename into...
(get_target_strict_alignment): ...this.
(get_target_double_float_alignment): New function.
(get_target_double_scalar_alignment): Likewise.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Signed_Integer_Subtype>:
Test the presence of an alignment clause for under-aligned integer
types. Take into account specific caps for the alignment of "double"
floating-point types and "double" or larger scalar types, as
parameterized by Target_Double_Float_Alignment and
Target_Double_Scalar_Alignment respectively.
(validate_alignment): Likewise.
* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Alignment>: Likewise.
(gigi): Initialize double_float_alignment and double_scalar_alignment.
* gcc-interface/utils.c (double_float_alignment): New global variable.
(double_scalar_alignment): Likewise.
(is_double_float_or_array): New predicate.
(is_double_scalar_or_array): Likewise.
From-SVN: r146675
Diffstat (limited to 'gcc/ada/gcc-interface/trans.c')
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 66 |
1 files changed, 51 insertions, 15 deletions
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index de6ac0b..d6aa7df 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -317,6 +317,10 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name, if (!Stack_Check_Probes_On_Target) set_stack_check_libfunc (gen_rtx_SYMBOL_REF (Pmode, "_gnat_stack_check")); + /* Retrieve alignment settings. */ + double_float_alignment = get_target_double_float_alignment (); + double_scalar_alignment = get_target_double_scalar_alignment (); + /* Record the builtin types. Define `integer' and `unsigned char' first so that dbx will output them first. */ record_builtin_type ("integer", integer_type_node); @@ -1066,12 +1070,10 @@ Pragma_to_gnu (Node_Id gnat_node) static tree Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) { - tree gnu_result = error_mark_node; - tree gnu_result_type; - tree gnu_expr; - bool prefix_unused = false; tree gnu_prefix = gnat_to_gnu (Prefix (gnat_node)); tree gnu_type = TREE_TYPE (gnu_prefix); + tree gnu_expr, gnu_result_type, gnu_result = error_mark_node; + bool prefix_unused = false; /* If the input is a NULL_EXPR, make a new one. */ if (TREE_CODE (gnu_prefix) == NULL_EXPR) @@ -1375,19 +1377,53 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) break; case Attr_Alignment: - if (TREE_CODE (gnu_prefix) == COMPONENT_REF - && (TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0))) - == RECORD_TYPE) - && (TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0))))) - gnu_prefix = TREE_OPERAND (gnu_prefix, 0); + { + unsigned int align; - gnu_type = TREE_TYPE (gnu_prefix); - gnu_result_type = get_unpadded_type (Etype (gnat_node)); - prefix_unused = true; + if (TREE_CODE (gnu_prefix) == COMPONENT_REF + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0))) + == RECORD_TYPE) + && (TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0))))) + gnu_prefix = TREE_OPERAND (gnu_prefix, 0); - gnu_result = size_int ((TREE_CODE (gnu_prefix) == COMPONENT_REF - ? DECL_ALIGN (TREE_OPERAND (gnu_prefix, 1)) - : TYPE_ALIGN (gnu_type)) / BITS_PER_UNIT); + gnu_type = TREE_TYPE (gnu_prefix); + gnu_result_type = get_unpadded_type (Etype (gnat_node)); + prefix_unused = true; + + if (TREE_CODE (gnu_prefix) == COMPONENT_REF) + align = DECL_ALIGN (TREE_OPERAND (gnu_prefix, 1)) / BITS_PER_UNIT; + else + { + Node_Id gnat_prefix = Prefix (gnat_node); + Entity_Id gnat_type = Etype (gnat_prefix); + unsigned int double_align; + bool is_capped_double, align_clause; + + /* If the default alignment of "double" or larger scalar types is + specifically capped and there is an alignment clause neither + on the type nor on the prefix itself, return the cap. */ + if ((double_align = double_float_alignment) > 0) + is_capped_double + = is_double_float_or_array (gnat_type, &align_clause); + else if ((double_align = double_scalar_alignment) > 0) + is_capped_double + = is_double_scalar_or_array (gnat_type, &align_clause); + else + is_capped_double = align_clause = false; + + if (is_capped_double + && Nkind (gnat_prefix) == N_Identifier + && Present (Alignment_Clause (Entity (gnat_prefix)))) + align_clause = true; + + if (is_capped_double && !align_clause) + align = double_align; + else + align = TYPE_ALIGN (gnu_type) / BITS_PER_UNIT; + } + + gnu_result = size_int (align); + } break; case Attr_First: |