public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch 0/6] scalar-storage-order merge (2)
@ 2015-10-06 10:57 Eric Botcazou
  2015-10-06 11:01 ` [patch 1/6] scalar-storage-order merge: Ada front-end Eric Botcazou
                   ` (7 more replies)
  0 siblings, 8 replies; 32+ messages in thread
From: Eric Botcazou @ 2015-10-06 10:57 UTC (permalink / raw)
  To: gcc-patches

Hi,

this is a repost of the diff of the scalar-storage-order branch vs mainline.
It contains the fixes suggested by Joseph for the C front-end and the doc, 
fixes for the handling of complex types, the new pragma scalar_storage_order 
and associated -fsso-struct switch for the C family of languages, and the 
adjustment for vector types suggested by Ramana, plus assorted fixes:
  https://gcc.gnu.org/ml/gcc-patches/2015-07/msg00024.html
  https://gcc.gnu.org/ml/gcc-patches/2015-07/msg00138.html
  https://gcc.gnu.org/ml/gcc-patches/2015-07/msg01500.html

See https://gcc.gnu.org/ml/gcc/2015-06/msg00126.html for the proposal.

I have split the diff into 6 pieces, which are interdependent and thus cannot 
be applied independently: 3 for the Ada, C and C++ front-ends, 1 for the bulk 
of the implementation, 1 for the rest and 1 for the testsuite.

It has been bootstrapped/regtested on x86_64-linux and powerpc-linux.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [patch 1/6] scalar-storage-order merge: Ada front-end
  2015-10-06 10:57 [patch 0/6] scalar-storage-order merge (2) Eric Botcazou
@ 2015-10-06 11:01 ` Eric Botcazou
  2015-10-12 22:23   ` Jeff Law
  2015-10-06 11:02 ` [patch 2/6] scalar-storage-order merge: C front-end Eric Botcazou
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 32+ messages in thread
From: Eric Botcazou @ 2015-10-06 11:01 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1751 bytes --]

This is the Ada front-end (in fact mostly gigi) part.

ada/
	* freeze.adb (Check_Component_Storage_Order): Skip a record component
	if it has Complex_Representation.
	(Freeze_Record_Type): If the type has Complex_Representation, skip
	the regular treatment of Scalar_Storage_Order attribute and instead
	issue a warning if it is present.
	* gcc-interface/gigi.h (set_reverse_storage_order_on_pad_type):
	Declare.
	* gcc-interface/decl.c (gnat_to_gnu_entity) <discrete_type>: Set the
	storage order on the enclosing record for a packed array type.
	<E_Array_Type>: Set the storage order.
	<E_Array_Subtype>: Likewise.
	<E_Record_Type>: Likewise.
	<E_Record_Subtype>: Likewise.
	(gnat_to_gnu_component_type): Set the reverse storage order on a
	padded type built for a non-bit-packed array.
	(gnat_to_gnu_field): Likewise.
	(components_to_record): Deal with TYPE_REVERSE_STORAGE_ORDER.
	* gcc-interface/utils.c (make_packable_type): Likewise.
	(pad_type_hasher::equal): Likewise.
	(gnat_types_compatible_p): Likewise.
	(unchecked_convert): Likewise.
	(set_reverse_storage_order_on_pad_type): New public function.
	* gcc-interface/trans.c (Attribute_to_gnu): Adjust call to
	get_inner_reference.
	* gcc-interface/utils2.c (build_unary_op): Likewise.
	(gnat_build_constructor): Deal with TYPE_REVERSE_STORAGE_ORDER.
	(gnat_rewrite_reference): Propagate REF_REVERSE_STORAGE_ORDER.

 freeze.adb             |  111 ++++++++++++++++++++++++++++-------------------
 gcc-interface/decl.c   |   49 +++++++++++++++++++--
 gcc-interface/gigi.h   |    3 +
 gcc-interface/trans.c  |    4 -
 gcc-interface/utils.c  |   84 +++++++++++++++++++++++++++++++------
 gcc-interface/utils2.c |   11 +++-
 6 files changed, 192 insertions(+), 70 deletions(-)

-- 
Eric Botcazou

[-- Attachment #2: sso-ada.diff --]
[-- Type: text/x-patch, Size: 22061 bytes --]

Index: ada/freeze.adb
===================================================================
--- ada/freeze.adb	(.../trunk/gcc)	(revision 228112)
+++ ada/freeze.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1196,9 +1196,14 @@ package body Freeze is
                      Attribute_Scalar_Storage_Order);
       Comp_ADC_Present := Present (Comp_ADC);
 
-      --  Case of record or array component: check storage order compatibility
-
-      if Is_Record_Type (Comp_Type) or else Is_Array_Type (Comp_Type) then
+      --  Case of record or array component: check storage order compatibility.
+      --  But, if the record has Complex_Representation, then it is treated as
+      --  a scalar in the back end so the storage order is irrelevant.
+
+      if (Is_Record_Type (Comp_Type)
+            and then not Has_Complex_Representation (Comp_Type))
+        or else Is_Array_Type (Comp_Type)
+      then
          Comp_SSO_Differs :=
            Reverse_Storage_Order (Encl_Type)
              /=
@@ -3958,61 +3963,73 @@ package body Freeze is
             Next_Entity (Comp);
          end loop;
 
-         --  Deal with default setting of reverse storage order
+         SSO_ADC := Get_Attribute_Definition_Clause
+                      (Rec, Attribute_Scalar_Storage_Order);
 
-         Set_SSO_From_Default (Rec);
+         --  If the record type has Complex_Representation, then it is treated
+         --  as a scalar in the back end so the storage order is irrelevant.
 
-         --  Check consistent attribute setting on component types
+         if Has_Complex_Representation (Rec) then
+            if Present (SSO_ADC) then
+               Error_Msg_N
+                  ("??storage order has no effect with "
+                   & "Complex_Representation", SSO_ADC);
+            end if;
 
-         SSO_ADC := Get_Attribute_Definition_Clause
-                      (Rec, Attribute_Scalar_Storage_Order);
+         else
+            --  Deal with default setting of reverse storage order
 
-         declare
-            Comp_ADC_Present : Boolean;
-         begin
-            Comp := First_Component (Rec);
-            while Present (Comp) loop
-               Check_Component_Storage_Order
-                 (Encl_Type        => Rec,
-                  Comp             => Comp,
-                  ADC              => SSO_ADC,
-                  Comp_ADC_Present => Comp_ADC_Present);
-               SSO_ADC_Component := SSO_ADC_Component or Comp_ADC_Present;
-               Next_Component (Comp);
-            end loop;
-         end;
+            Set_SSO_From_Default (Rec);
+
+            --  Check consistent attribute setting on component types
 
-         --  Now deal with reverse storage order/bit order issues
+            declare
+               Comp_ADC_Present : Boolean;
+            begin
+               Comp := First_Component (Rec);
+               while Present (Comp) loop
+                  Check_Component_Storage_Order
+                    (Encl_Type        => Rec,
+                     Comp             => Comp,
+                     ADC              => SSO_ADC,
+                     Comp_ADC_Present => Comp_ADC_Present);
+                  SSO_ADC_Component := SSO_ADC_Component or Comp_ADC_Present;
+                  Next_Component (Comp);
+               end loop;
+            end;
 
-         if Present (SSO_ADC) then
+            --  Now deal with reverse storage order/bit order issues
 
-            --  Check compatibility of Scalar_Storage_Order with Bit_Order, if
-            --  the former is specified.
+            if Present (SSO_ADC) then
 
-            if Reverse_Bit_Order (Rec) /= Reverse_Storage_Order (Rec) then
+               --  Check compatibility of Scalar_Storage_Order with Bit_Order,
+               --  if the former is specified.
 
-               --  Note: report error on Rec, not on SSO_ADC, as ADC may apply
-               --  to some ancestor type.
+               if Reverse_Bit_Order (Rec) /= Reverse_Storage_Order (Rec) then
 
-               Error_Msg_Sloc := Sloc (SSO_ADC);
-               Error_Msg_N
-                 ("scalar storage order for& specified# inconsistent with "
-                  & "bit order", Rec);
-            end if;
+                  --  Note: report error on Rec, not on SSO_ADC, as ADC may
+                  --  apply to some ancestor type.
 
-            --  Warn if there is an Scalar_Storage_Order attribute definition
-            --  clause but no component clause, no component that itself has
-            --  such an attribute definition, and no pragma Pack.
-
-            if not (Placed_Component
-                      or else
-                    SSO_ADC_Component
-                      or else
-                    Is_Packed (Rec))
-            then
-               Error_Msg_N
-                 ("??scalar storage order specified but no component clause",
-                  SSO_ADC);
+                  Error_Msg_Sloc := Sloc (SSO_ADC);
+                  Error_Msg_N
+                    ("scalar storage order for& specified# inconsistent with "
+                     & "bit order", Rec);
+               end if;
+
+               --  Warn if there is a Scalar_Storage_Order attribute definition
+               --  clause but no component clause, no component that itself has
+               --  such an attribute definition, and no pragma Pack.
+
+               if not (Placed_Component
+                         or else
+                       SSO_ADC_Component
+                         or else
+                       Is_Packed (Rec))
+               then
+                  Error_Msg_N
+                    ("??scalar storage order specified but no component "
+                     & "clause", SSO_ADC);
+               end if;
             end if;
          end if;
 
Index: ada/gcc-interface/utils.c
===================================================================
--- ada/gcc-interface/utils.c	(.../trunk/gcc)	(revision 228112)
+++ ada/gcc-interface/utils.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -963,6 +963,7 @@ make_packable_type (tree type, bool in_r
   TYPE_NAME (new_type) = TYPE_NAME (type);
   TYPE_JUSTIFIED_MODULAR_P (new_type) = TYPE_JUSTIFIED_MODULAR_P (type);
   TYPE_CONTAINS_TEMPLATE_P (new_type) = TYPE_CONTAINS_TEMPLATE_P (type);
+  TYPE_REVERSE_STORAGE_ORDER (new_type) = TYPE_REVERSE_STORAGE_ORDER (type);
   if (TREE_CODE (type) == RECORD_TYPE)
     TYPE_PADDING_P (new_type) = TYPE_PADDING_P (type);
 
@@ -1181,14 +1182,15 @@ pad_type_hasher::equal (pad_type_hash *t
   type1 = t1->type;
   type2 = t2->type;
 
-  /* We consider that the padded types are equivalent if they pad the same
-     type and have the same size, alignment and RM size.  Taking the mode
-     into account is redundant since it is determined by the others.  */
+  /* We consider that the padded types are equivalent if they pad the same type
+     and have the same size, alignment, RM size and storage order.  Taking the
+     mode into account is redundant since it is determined by the others.  */
   return
     TREE_TYPE (TYPE_FIELDS (type1)) == TREE_TYPE (TYPE_FIELDS (type2))
     && TYPE_SIZE (type1) == TYPE_SIZE (type2)
     && TYPE_ALIGN (type1) == TYPE_ALIGN (type2)
-    && TYPE_ADA_SIZE (type1) == TYPE_ADA_SIZE (type2);
+    && TYPE_ADA_SIZE (type1) == TYPE_ADA_SIZE (type2)
+    && TYPE_REVERSE_STORAGE_ORDER (type1) == TYPE_REVERSE_STORAGE_ORDER (type2);
 }
 
 /* Look up the padded TYPE in the hash table and return its canonical version
@@ -1458,6 +1460,31 @@ built:
 
   return record;
 }
+
+/* Return a copy of the padded TYPE but with reverse storage order.  */
+
+tree
+set_reverse_storage_order_on_pad_type (tree type)
+{
+  tree field, canonical_pad_type;
+
+#ifdef ENABLE_CHECKING
+  /* If the inner type is not scalar then the function does nothing.  */
+  tree inner_type = TREE_TYPE (TYPE_FIELDS (type));
+  gcc_assert (!AGGREGATE_TYPE_P (inner_type) && !VECTOR_TYPE_P (inner_type));
+#endif
+
+  /* This is required for the canonicalization.  */
+  gcc_assert (TREE_CONSTANT (TYPE_SIZE (type)));
+
+  field = copy_node (TYPE_FIELDS (type));
+  type = copy_type (type);
+  DECL_CONTEXT (field) = type;
+  TYPE_FIELDS (type) = field;
+  TYPE_REVERSE_STORAGE_ORDER (type) = 1;
+  canonical_pad_type = lookup_and_insert_pad_type (type);
+  return canonical_pad_type ? canonical_pad_type : type;
+}
 \f
 /* Relate the alias sets of GNU_NEW_TYPE and GNU_OLD_TYPE according to OP.
    If this is a multi-dimensional array type, do this recursively.
@@ -3365,7 +3392,7 @@ gnat_types_compatible_p (tree t1, tree t
     return 1;
 
   /* Array types are also compatible if they are constrained and have the same
-     domain(s) and the same component type.  */
+     domain(s), the same component type and the same scalar storage order.  */
   if (code == ARRAY_TYPE
       && (TYPE_DOMAIN (t1) == TYPE_DOMAIN (t2)
 	  || (TYPE_DOMAIN (t1)
@@ -3376,7 +3403,8 @@ gnat_types_compatible_p (tree t1, tree t
 				     TYPE_MAX_VALUE (TYPE_DOMAIN (t2)))))
       && (TREE_TYPE (t1) == TREE_TYPE (t2)
 	  || (TREE_CODE (TREE_TYPE (t1)) == ARRAY_TYPE
-	      && gnat_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))))
+	      && gnat_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))))
+      && TYPE_REVERSE_STORAGE_ORDER (t1) == TYPE_REVERSE_STORAGE_ORDER (t2))
     return 1;
 
   return 0;
@@ -4857,17 +4885,38 @@ unchecked_convert (tree type, tree expr,
     }
 
   /* If we are converting to an integral type whose precision is not equal
-     to its size, first unchecked convert to a record type that contains an
-     field of the given precision.  Then extract the field.  */
+     to its size, first unchecked convert to a record type that contains a
+     field of the given precision.  Then extract the result from the field.
+
+     There is a subtlety if the source type is an aggregate type with reverse
+     storage order because its representation is not contiguous in the native
+     storage order, i.e. a direct unchecked conversion to an integral type
+     with N bits of precision cannot read the first N bits of the aggregate
+     type.  To overcome it, we do an unchecked conversion to an integral type
+     with reverse storage order and return the resulting value.  This also
+     ensures that the result of the unchecked conversion doesn't depend on
+     the endianness of the target machine, but only on the storage order of
+     the aggregate type.
+
+     Finally, for the sake of consistency, we do the unchecked conversion
+     to an integral type with reverse storage order as soon as the source
+     type is an aggregate type with reverse storage order, even if there
+     are no considerations of precision or size involved.  */
   else if (INTEGRAL_TYPE_P (type)
 	   && TYPE_RM_SIZE (type)
-	   && 0 != compare_tree_int (TYPE_RM_SIZE (type),
-				     GET_MODE_BITSIZE (TYPE_MODE (type))))
+	   && (0 != compare_tree_int (TYPE_RM_SIZE (type),
+				      GET_MODE_BITSIZE (TYPE_MODE (type)))
+	       || (AGGREGATE_TYPE_P (etype)
+		   && TYPE_REVERSE_STORAGE_ORDER (etype))))
     {
       tree rec_type = make_node (RECORD_TYPE);
       unsigned HOST_WIDE_INT prec = TREE_INT_CST_LOW (TYPE_RM_SIZE (type));
       tree field_type, field;
 
+      if (AGGREGATE_TYPE_P (etype))
+	TYPE_REVERSE_STORAGE_ORDER (rec_type)
+	  = TYPE_REVERSE_STORAGE_ORDER (etype);
+
       if (TYPE_UNSIGNED (type))
 	field_type = make_unsigned_type (prec);
       else
@@ -4886,11 +4935,16 @@ unchecked_convert (tree type, tree expr,
 
   /* Similarly if we are converting from an integral type whose precision is
      not equal to its size, first copy into a field of the given precision
-     and unchecked convert the record type.  */
+     and unchecked convert the record type.
+
+     The same considerations as above apply if the target type is an aggregate
+     type with reverse storage order and we also proceed similarly.  */
   else if (INTEGRAL_TYPE_P (etype)
 	   && TYPE_RM_SIZE (etype)
-	   && 0 != compare_tree_int (TYPE_RM_SIZE (etype),
-				     GET_MODE_BITSIZE (TYPE_MODE (etype))))
+	   && (0 != compare_tree_int (TYPE_RM_SIZE (etype),
+				      GET_MODE_BITSIZE (TYPE_MODE (etype)))
+	       || (AGGREGATE_TYPE_P (type)
+		   && TYPE_REVERSE_STORAGE_ORDER (type))))
     {
       tree rec_type = make_node (RECORD_TYPE);
       unsigned HOST_WIDE_INT prec = TREE_INT_CST_LOW (TYPE_RM_SIZE (etype));
@@ -4898,6 +4952,10 @@ unchecked_convert (tree type, tree expr,
       vec_alloc (v, 1);
       tree field_type, field;
 
+      if (AGGREGATE_TYPE_P (type))
+	TYPE_REVERSE_STORAGE_ORDER (rec_type)
+	  = TYPE_REVERSE_STORAGE_ORDER (type);
+
       if (TYPE_UNSIGNED (etype))
 	field_type = make_unsigned_type (prec);
       else
Index: ada/gcc-interface/decl.c
===================================================================
--- ada/gcc-interface/decl.c	(.../trunk/gcc)	(revision 228112)
+++ ada/gcc-interface/decl.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1808,6 +1808,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 	  TYPE_ALIGN (gnu_type)
 	    = align > 0 ? align : TYPE_ALIGN (gnu_field_type);
 
+	  /* Propagate the reverse storage order flag to the record type so
+	     that the required byte swapping is performed when retrieving the
+	     enclosed modular value.  */
+	  TYPE_REVERSE_STORAGE_ORDER (gnu_type)
+	    = Reverse_Storage_Order (Original_Array_Type (gnat_entity));
+
 	  relate_alias_sets (gnu_type, gnu_field_type, ALIAS_SET_COPY);
 
 	  /* Don't declare the field as addressable since we won't be taking
@@ -2155,8 +2161,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 	for (index = ndim - 1; index >= 0; index--)
 	  {
 	    tem = build_nonshared_array_type (tem, gnu_index_types[index]);
-	    if (Reverse_Storage_Order (gnat_entity) && !GNAT_Mode)
-	      sorry ("non-default Scalar_Storage_Order");
+	    if (index == ndim - 1)
+	      TYPE_REVERSE_STORAGE_ORDER (tem)
+		= Reverse_Storage_Order (gnat_entity);
 	    TYPE_MULTI_ARRAY_P (tem) = (index > 0);
 	    if (array_type_has_nonaliased_component (tem, gnat_entity))
 	      TYPE_NONALIASED_COMPONENT (tem) = 1;
@@ -2519,6 +2526,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 	    {
 	      gnu_type = build_nonshared_array_type (gnu_type,
 						     gnu_index_types[index]);
+	      if (index == ndim - 1)
+		TYPE_REVERSE_STORAGE_ORDER (gnu_type)
+		  = Reverse_Storage_Order (gnat_entity);
 	      TYPE_MULTI_ARRAY_P (gnu_type) = (index > 0);
 	      if (array_type_has_nonaliased_component (gnu_type, gnat_entity))
 		TYPE_NONALIASED_COMPONENT (gnu_type) = 1;
@@ -2881,8 +2891,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 	gnu_type = make_node (tree_code_for_record_type (gnat_entity));
 	TYPE_NAME (gnu_type) = gnu_entity_name;
 	TYPE_PACKED (gnu_type) = (packed != 0) || has_rep;
-	if (Reverse_Storage_Order (gnat_entity) && !GNAT_Mode)
-	  sorry ("non-default Scalar_Storage_Order");
+	TYPE_REVERSE_STORAGE_ORDER (gnu_type)
+	  = Reverse_Storage_Order (gnat_entity);
 	process_attributes (&gnu_type, &attr_list, true, gnat_entity);
 
 	if (!definition)
@@ -3292,6 +3302,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 	      gnu_type = make_node (RECORD_TYPE);
 	      TYPE_NAME (gnu_type) = gnu_entity_name;
 	      TYPE_PACKED (gnu_type) = TYPE_PACKED (gnu_base_type);
+	      TYPE_REVERSE_STORAGE_ORDER (gnu_type)
+		= Reverse_Storage_Order (gnat_entity);
 	      process_attributes (&gnu_type, &attr_list, true, gnat_entity);
 
 	      /* Set the size, alignment and alias set of the new type to
@@ -3346,6 +3358,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 			TYPE_NAME (new_variant)
 			  = concat_name (TYPE_NAME (gnu_type),
 					 IDENTIFIER_POINTER (suffix));
+			TYPE_REVERSE_STORAGE_ORDER (new_variant)
+			  = TYPE_REVERSE_STORAGE_ORDER (gnu_type);
 			copy_and_substitute_in_size (new_variant, old_variant,
 						     gnu_subst_list);
 			v->new_type = new_variant;
@@ -5553,6 +5567,16 @@ gnat_to_gnu_component_type (Entity_Id gn
 			  gnat_array);
     }
 
+  /* If the component type is a padded type made for a non-bit-packed array
+     of scalars with reverse storage order, we need to propagate the reverse
+     storage order to the padding type since it is the innermost enclosing
+     aggregate type around the scalar.  */
+  if (TYPE_IS_PADDING_P (gnu_type)
+      && Reverse_Storage_Order (gnat_array)
+      && !Is_Bit_Packed_Array (gnat_array)
+      && Is_Scalar_Type (gnat_type))
+    gnu_type = set_reverse_storage_order_on_pad_type (gnu_type);
+
   if (Has_Volatile_Components (gnat_array))
     {
       const int quals
@@ -6724,6 +6748,15 @@ gnat_to_gnu_field (Entity_Id gnat_field,
   else
     gnu_pos = NULL_TREE;
 
+  /* If the field's type is a padded type made for a scalar field of a record
+     type with reverse storage order, we need to propagate the reverse storage
+     order to the padding type since it is the innermost enclosing aggregate
+     type around the scalar.  */
+  if (TYPE_IS_PADDING_P (gnu_field_type)
+      && TYPE_REVERSE_STORAGE_ORDER (gnu_record_type)
+      && Is_Scalar_Type (gnat_field_type))
+    gnu_field_type = set_reverse_storage_order_on_pad_type (gnu_field_type);
+
   gcc_assert (TREE_CODE (gnu_field_type) != RECORD_TYPE
 	      || !TYPE_CONTAINS_TEMPLATE_P (gnu_field_type));
 
@@ -7040,6 +7073,8 @@ components_to_record (tree gnu_record_ty
 	  TYPE_NAME (gnu_union_type) = gnu_union_name;
 	  TYPE_ALIGN (gnu_union_type) = 0;
 	  TYPE_PACKED (gnu_union_type) = TYPE_PACKED (gnu_record_type);
+	  TYPE_REVERSE_STORAGE_ORDER (gnu_union_type)
+	    = TYPE_REVERSE_STORAGE_ORDER (gnu_record_type);
 	}
 
       /* If all the fields down to this level have a rep clause, find out
@@ -7091,6 +7126,8 @@ components_to_record (tree gnu_record_ty
 	     record actually gets only the alignment required.  */
 	  TYPE_ALIGN (gnu_variant_type) = TYPE_ALIGN (gnu_record_type);
 	  TYPE_PACKED (gnu_variant_type) = TYPE_PACKED (gnu_record_type);
+	  TYPE_REVERSE_STORAGE_ORDER (gnu_variant_type)
+	    = TYPE_REVERSE_STORAGE_ORDER (gnu_record_type);
 
 	  /* Similarly, if the outer record has a size specified and all
 	     the fields have a rep clause, we can propagate the size.  */
@@ -7183,6 +7220,8 @@ components_to_record (tree gnu_record_ty
 		     position at this level.  */
 		  tree gnu_rep_type = make_node (RECORD_TYPE);
 		  tree gnu_rep_part;
+		  TYPE_REVERSE_STORAGE_ORDER (gnu_rep_type)
+		    = TYPE_REVERSE_STORAGE_ORDER (gnu_variant_type);
 		  finish_record_type (gnu_rep_type, NULL_TREE, 0, debug_info);
 		  gnu_rep_part
 		    = create_rep_part (gnu_rep_type, gnu_variant_type,
@@ -7390,6 +7429,8 @@ components_to_record (tree gnu_record_ty
 	gnu_field_list = gnu_rep_list;
       else
 	{
+	  TYPE_REVERSE_STORAGE_ORDER (gnu_rep_type)
+	    = TYPE_REVERSE_STORAGE_ORDER (gnu_record_type);
 	  finish_record_type (gnu_rep_type, gnu_rep_list, 1, debug_info);
 
 	  /* If FIRST_FREE_POS is nonzero, we need to ensure that the fields
Index: ada/gcc-interface/utils2.c
===================================================================
--- ada/gcc-interface/utils2.c	(.../trunk/gcc)	(revision 228112)
+++ ada/gcc-interface/utils2.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1412,11 +1412,11 @@ build_unary_op (enum tree_code op_code,
 	      HOST_WIDE_INT bitpos;
 	      tree offset, inner;
 	      machine_mode mode;
-	      int unsignedp, volatilep;
+	      int unsignedp, reversep, volatilep;
 
 	      inner = get_inner_reference (operand, &bitsize, &bitpos, &offset,
-					   &mode, &unsignedp, &volatilep,
-					   false);
+					   &mode, &unsignedp, &reversep,
+					   &volatilep, false);
 
 	      /* If INNER is a padding type whose field has a self-referential
 		 size, convert to that inner type.  We know the offset is zero
@@ -1920,7 +1920,9 @@ gnat_build_constructor (tree type, vec<c
 	  || (TREE_CODE (type) == RECORD_TYPE
 	      && CONSTRUCTOR_BITFIELD_P (obj)
 	      && !initializer_constant_valid_for_bitfield_p (val))
-	  || !initializer_constant_valid_p (val, TREE_TYPE (val)))
+	  || !initializer_constant_valid_p (val,
+					    TREE_TYPE (val),
+					    TYPE_REVERSE_STORAGE_ORDER (type)))
 	allconstant = false;
 
       if (!TREE_READONLY (val))
@@ -2748,6 +2750,7 @@ gnat_rewrite_reference (tree ref, rewrit
 		       gnat_rewrite_reference (TREE_OPERAND (ref, 0), func,
 					       data, init),
 		       TREE_OPERAND (ref, 1), TREE_OPERAND (ref, 2));
+      REF_REVERSE_STORAGE_ORDER (result) = REF_REVERSE_STORAGE_ORDER (ref);
       break;
 
     case ARRAY_REF:
Index: ada/gcc-interface/gigi.h
===================================================================
--- ada/gcc-interface/gigi.h	(.../trunk/gcc)	(revision 228112)
+++ ada/gcc-interface/gigi.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -154,6 +154,9 @@ extern tree maybe_pad_type (tree type, t
 			    bool is_user_type, bool definition,
 			    bool set_rm_size);
 
+/* Return a copy of the padded TYPE but with reverse storage order.  */
+extern tree set_reverse_storage_order_on_pad_type (tree type);
+
 enum alias_set_op
 {
   ALIAS_SET_COPY,
Index: ada/gcc-interface/trans.c
===================================================================
--- ada/gcc-interface/trans.c	(.../trunk/gcc)	(revision 228112)
+++ ada/gcc-interface/trans.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -2170,7 +2170,7 @@ Attribute_to_gnu (Node_Id gnat_node, tre
 	tree gnu_field_offset;
 	tree gnu_inner;
 	machine_mode mode;
-	int unsignedp, volatilep;
+	int unsignedp, reversep, volatilep;
 
 	gnu_result_type = get_unpadded_type (Etype (gnat_node));
 	gnu_prefix = remove_conversions (gnu_prefix, true);
@@ -2192,7 +2192,7 @@ Attribute_to_gnu (Node_Id gnat_node, tre
 			  && TREE_CODE (gnu_prefix) == FIELD_DECL));
 
 	get_inner_reference (gnu_prefix, &bitsize, &bitpos, &gnu_offset,
-			     &mode, &unsignedp, &volatilep, false);
+			     &mode, &unsignedp, &reversep, &volatilep, false);
 
 	if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
 	  {

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [patch 2/6] scalar-storage-order merge: C front-end
  2015-10-06 10:57 [patch 0/6] scalar-storage-order merge (2) Eric Botcazou
  2015-10-06 11:01 ` [patch 1/6] scalar-storage-order merge: Ada front-end Eric Botcazou
@ 2015-10-06 11:02 ` Eric Botcazou
  2015-10-13 11:32   ` Jeff Law
  2015-10-28 16:48   ` Joseph Myers
  2015-10-06 11:03 ` [patch 3/6] scalar-storage-order merge: C++ front-end Eric Botcazou
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 32+ messages in thread
From: Eric Botcazou @ 2015-10-06 11:02 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1925 bytes --]

This is the C front-end + C family part.

	* doc/extend.texi (type attributes): Document scalar_storage_order.
	(Structure-Packing Pragmas): Rename into...
	(Structure-Layout Pragmas): ...this.  Document scalar_storage_order.
	* doc/invoke.texi (C Dialect Options): Document -fsso-struct
	(Warnings): Document -Wno-scalar-storage-order.
	* flag-types.h (enum scalar_storage_order_kind): New enumeration.
c-family/
	* c-common.c (c_common_attributes): Add scalar_storage_order.
	(handle_scalar_storage_order_attribute): New function.
	* c-pragma.c (global_sso): New variable.
	(maybe_apply_pragma_scalar_storage_order): New function.
	(handle_pragma_scalar_storage_order): Likewise.
	(init_pragma): Register scalar_storage_order.
	* c-pragma.h (maybe_apply_pragma_scalar_storage_order): Declare.
	* c.opt (Wscalar-storage-order): New warning.
	(fsso-struct=): New option.
c/
	* c-decl.c (finish_struct): If the structure has reverse storage
	order, rewrite the type of array fields with scalar component.  Call
	maybe_apply_pragma_scalar_storage_order on entry.
	* c-typeck.c (build_unary_op) <ADDR_EXPR>: Remove left-overs.  Issue
	errors on bit-fields and reverse SSO here and not...
	(c_mark_addressable): ...here.
	(output_init_element): Adjust call to initializer_constant_valid_p.
	(c_build_qualified_type): Propagate TYPE_REVERSE_STORAGE_ORDER.

 doc/extend.texi     |   69 ++++++++++++++++++++++++++++++++++++++++++--------
 doc/invoke.texi     |   22 +++++++++++++++-
 flag-types.h        |    9 +++++-
 c-family/c.opt      |   17 ++++++++++++
 c-family/c-common.c |   47 ++++++++++++++++++++++++++++++++++-
 c-family/c-pragma.c |   50 +++++++++++++++++++++++++++++++++++++
 c-family/c-pragma.h |    1 
 c/c-typeck.c        |   66 ++++++++++++++++++++++++++++++++++---------------
 c/c-decl.c          |   48 +++++++++++++++++++++++++-----------
 8 files changed, 273 insertions(+), 47 deletions(-)

-- 
Eric Botcazou

[-- Attachment #2: sso-c.diff --]
[-- Type: text/x-patch, Size: 21810 bytes --]

Index: doc/extend.texi
===================================================================
--- doc/extend.texi	(.../trunk/gcc)	(revision 228112)
+++ doc/extend.texi	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -6310,6 +6310,42 @@ of the structure or union is placed to m
 attached to an @code{enum} definition, it indicates that the smallest
 integral type should be used.
 
+@item scalar_storage_order ("@var{endianness}")
+@cindex @code{scalar_storage_order} type attribute
+When attached to a @code{union} or a @code{struct}, this attribute sets
+the storage order, aka endianness, of the scalar fields of the type, as
+well as the array fields whose component is scalar.  The supported
+endianness are @code{big-endian} and @code{little-endian}.  The attribute
+has no effects on fields which are themselves a @code{union}, a @code{struct}
+or an array whose component is a @code{union} or a @code{struct}, and it is
+possible to have fields with a different scalar storage order than the
+enclosing type.
+
+This attribute is supported only for targets that use a uniform default
+scalar storage order (fortunately, most of them), i.e. targets that store
+the scalars either all in big-endian or all in little-endian.
+
+Additional restrictions are enforced for types with the reverse scalar
+storage order with regard to the scalar storage order of the target:
+
+@itemize
+@item Taking the address of a scalar field of a @code{union} or a
+@code{struct} with reverse scalar storage order is not permitted and will
+yield an error
+@item Taking the address of an array field, whose component is scalar, of
+a @code{union} or a @code{struct} with reverse scalar storage order is
+permitted but will yield a warning, unless @option{-Wno-scalar-storage-order}
+is specified
+@item Taking the address of a @code{union} or a @code{struct} with reverse
+scalar storage order is permitted
+@end itemize
+
+These restrictions exist because the storage order attribute is lost when
+the address of a scalar or the address of an array with scalar component
+is taken, so storing indirectly through this address will generally not work.
+The second case is nevertheless allowed to be able to perform a block copy
+from or to the array.
+
 @item transparent_union
 @cindex @code{transparent_union} type attribute
 
@@ -18326,7 +18362,7 @@ for further explanation.
 * Darwin Pragmas::
 * Solaris Pragmas::
 * Symbol-Renaming Pragmas::
-* Structure-Packing Pragmas::
+* Structure-Layout Pragmas::
 * Weak Pragmas::
 * Diagnostic Pragmas::
 * Visibility Pragmas::
@@ -18602,8 +18638,8 @@ the name does not change.
 always the C-language name.
 @end enumerate
 
-@node Structure-Packing Pragmas
-@subsection Structure-Packing Pragmas
+@node Structure-Layout Pragmas
+@subsection Structure-Layout Pragmas
 
 For compatibility with Microsoft Windows compilers, GCC supports a
 set of @code{#pragma} directives that change the maximum alignment of
@@ -18626,17 +18662,30 @@ multiple @code{#pragma pack(@var{n})} in
 @code{#pragma pack(pop)}.
 @end enumerate
 
-Some targets, e.g.@: x86 and PowerPC, support the @code{ms_struct}
-@code{#pragma} which lays out a structure as the documented
-@code{__attribute__ ((ms_struct))}.
+Some targets, e.g.@: x86 and PowerPC, support the @code{#pragma ms_struct}
+directive which lays out structures, unions and classes subsequently defined
+as the documented @code{__attribute__ ((ms_struct))}.
+
 @enumerate
-@item @code{#pragma ms_struct on} turns on the layout for structures
-declared.
-@item @code{#pragma ms_struct off} turns off the layout for structures
-declared.
+@item @code{#pragma ms_struct on} turns on the Microsoft layout.
+@item @code{#pragma ms_struct off} turns off the Microsoft layout.
 @item @code{#pragma ms_struct reset} goes back to the default layout.
 @end enumerate
 
+Most targets also support the @code{#pragma scalar_storage_order} directive
+which lays out structures, unions and classes subsequently defined as the
+documented @code{__attribute__ ((scalar_storage_order))}.
+
+@enumerate
+@item @code{#pragma scalar_storage_order big-endian} sets the storage order
+of the scalar fields to big-endian.
+@item @code{#pragma scalar_storage_order little-endian} sets the storage order
+of the scalar fields to little-endian.
+@item @code{#pragma scalar_storage_order default} goes back to the endianness
+that was in effect when compilation started (see also command-line option
+@option{-fsso-struct=@var{endianness}} @pxref{C Dialect Options}).
+@end enumerate
+
 @node Weak Pragmas
 @subsection Weak Pragmas
 
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(.../trunk/gcc)	(revision 228112)
+++ doc/invoke.texi	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -169,10 +169,11 @@ in the following sections.
 -aux-info @var{filename} -fallow-parameterless-variadic-functions @gol
 -fno-asm  -fno-builtin  -fno-builtin-@var{function} @gol
 -fhosted  -ffreestanding -fopenacc -fopenmp -fopenmp-simd @gol
--fms-extensions -fplan9-extensions -trigraphs -traditional -traditional-cpp @gol
+-fms-extensions -fplan9-extensions -fsso-struct=@var{endianness}
 -fallow-single-precision  -fcond-mismatch -flax-vector-conversions @gol
 -fsigned-bitfields  -fsigned-char @gol
--funsigned-bitfields  -funsigned-char}
+-funsigned-bitfields  -funsigned-char @gol
+-trigraphs -traditional -traditional-cpp}
 
 @item C++ Language Options
 @xref{C++ Dialect Options,,Options Controlling C++ Dialect}.
@@ -278,6 +279,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wshift-overflow -Wshift-overflow=@var{n} @gol
 -Wshift-count-negative -Wshift-count-overflow -Wshift-negative-value @gol
 -Wsign-compare  -Wsign-conversion -Wfloat-conversion @gol
+-Wno-scalar-storage-order @gol
 -Wsizeof-pointer-memaccess  -Wsizeof-array-argument @gol
 -Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol
 -Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol
@@ -2069,6 +2071,17 @@ These options control whether a bit-fiel
 declaration does not use either @code{signed} or @code{unsigned}.  By
 default, such a bit-field is signed, because this is consistent: the
 basic integer types such as @code{int} are signed types.
+
+@item -fsso-struct=@var{endianness}
+@opindex fsso-struct
+Set the default scalar storage order of structures, unions and classes to
+the specified endianness.  The accepted values are @samp{big-endian} and
+@samp{little-endian}.  If the option is not passed, the compiler uses the
+native endianness of the target.
+
+@strong{Warning:} the @option{-fsso-struct} switch causes GCC to generate
+code that is not binary compatible with code generated without it if the
+specified endianness is not the native endianness of the target.
 @end table
 
 @node C++ Dialect Options
@@ -5087,6 +5100,11 @@ This includes conversions from real to i
 real to lower precision real values.  This option is also enabled by
 @option{-Wconversion}.
 
+@item -Wno-scalar-storage-order
+@opindex -Wno-scalar-storage-order
+@opindex -Wscalar-storage-order
+Do not warn on suspicious constructs involving reverse scalar storage order.
+
 @item -Wsized-deallocation @r{(C++ and Objective-C++ only)}
 @opindex Wsized-deallocation
 @opindex Wno-sized-deallocation
Index: flag-types.h
===================================================================
--- flag-types.h	(.../trunk/gcc)	(revision 228112)
+++ flag-types.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -158,7 +158,6 @@ enum stack_check_type
 
 /* Names for the different levels of -Wstrict-overflow=N.  The numeric
    values here correspond to N.  */
-
 enum warn_strict_overflow_code
 {
   /* Overflow warning that should be issued with -Wall: a questionable
@@ -188,6 +187,13 @@ enum fp_contract_mode {
   FP_CONTRACT_FAST = 2
 };
 
+/* Scalar storage order kind.  */
+enum scalar_storage_order_kind {
+  SSO_NATIVE = 0,
+  SSO_BIG_ENDIAN,
+  SSO_LITTLE_ENDIAN
+};
+
 /* Vectorizer cost-model.  */
 enum vect_cost_model {
   VECT_COST_MODEL_UNLIMITED = 0,
@@ -196,7 +202,6 @@ enum vect_cost_model {
   VECT_COST_MODEL_DEFAULT = 3
 };
 
-
 /* Different instrumentation modes.  */
 enum sanitize_code {
   /* AddressSanitizer.  */
Index: c-family/c.opt
===================================================================
--- c-family/c.opt	(.../trunk/gcc)	(revision 228112)
+++ c-family/c.opt	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -784,6 +784,10 @@ Wreturn-type
 C ObjC C++ ObjC++ Var(warn_return_type) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
 Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++)
 
+Wscalar-storage-order
+C ObjC C++ ObjC++ Init(1) Warning
+Warn on suspicious constructs involving reverse scalar storage order
+
 Wselector
 ObjC ObjC++ Var(warn_selector) Warning
 Warn if a selector has multiple methods
@@ -1447,6 +1451,19 @@ Enable C++14 sized deallocation support
 fsquangle
 C++ ObjC++ Ignore Warn(switch %qs is no longer supported)
 
+fsso-struct=
+C C++ Joined RejectNegative Enum(sso_struct) Var(default_sso) Init(SSO_NATIVE)
+-fsso-struct=[big-endian|little-endian] Set the default scalar storage order
+
+Enum
+Name(sso_struct) Type(enum scalar_storage_order_kind) UnknownError(unrecognized scalar storage order value %qs)
+
+EnumValue
+Enum(sso_struct) String(big-endian) Value(SSO_BIG_ENDIAN)
+
+EnumValue
+Enum(sso_struct) String(little-endian) Value(SSO_LITTLE_ENDIAN)
+
 fstats
 C++ ObjC++ Var(flag_detailed_statistics)
 Display statistics accumulated during compilation
Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c	(.../trunk/gcc)	(revision 228112)
+++ c-family/c-common.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -344,6 +344,8 @@ static tree handle_no_reorder_attribute
 static tree handle_const_attribute (tree *, tree, tree, int, bool *);
 static tree handle_transparent_union_attribute (tree *, tree, tree,
 						int, bool *);
+static tree handle_scalar_storage_order_attribute (tree *, tree, tree,
+						   int, bool *);
 static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
 static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
 static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
@@ -692,6 +694,8 @@ const struct attribute_spec c_common_att
   /* The same comments as for noreturn attributes apply to const ones.  */
   { "const",                  0, 0, true,  false, false,
 			      handle_const_attribute, false },
+  { "scalar_storage_order",   1, 1, false, false, false,
+			      handle_scalar_storage_order_attribute, false },
   { "transparent_union",      0, 0, false, false, false,
 			      handle_transparent_union_attribute, false },
   { "constructor",            0, 1, true,  false, false,
@@ -7636,6 +7640,48 @@ handle_const_attribute (tree *node, tree
   return NULL_TREE;
 }
 
+/* Handle a "scalar_storage_order" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_scalar_storage_order_attribute (tree *node, tree name, tree args,
+				       int flags, bool *no_add_attrs)
+{
+  tree id = TREE_VALUE (args);
+  tree type;
+
+  if (TREE_CODE (*node) == TYPE_DECL
+      && ! (flags & ATTR_FLAG_CXX11))
+    node = &TREE_TYPE (*node);
+  type = *node;
+
+  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+    error ("scalar_storage_order is not supported");
+
+  if (RECORD_OR_UNION_TYPE_P (type))
+    {
+      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+	goto ignored;
+
+      if (TREE_CODE (id) == STRING_CST
+	  && strcmp (TREE_STRING_POINTER (id), "big-endian") == 0)
+	TYPE_REVERSE_STORAGE_ORDER (type) = !BYTES_BIG_ENDIAN;
+      else if (TREE_CODE (id) == STRING_CST
+	       && strcmp (TREE_STRING_POINTER (id), "little-endian") == 0)
+	TYPE_REVERSE_STORAGE_ORDER (type) = BYTES_BIG_ENDIAN;
+      else
+	error ("scalar_storage_order argument must be one of \"big-endian\" "
+	       "or \"little-endian\"");
+
+      return NULL_TREE;
+    }
+
+ ignored:
+  warning (OPT_Wattributes, "%qE attribute ignored", name);
+  *no_add_attrs = true;
+  return NULL_TREE;
+}
+
 /* Handle a "transparent_union" attribute; arguments as in
    struct attribute_spec.handler.  */
 
@@ -7648,7 +7694,6 @@ handle_transparent_union_attribute (tree
 
   *no_add_attrs = true;
 
-
   if (TREE_CODE (*node) == TYPE_DECL
       && ! (flags & ATTR_FLAG_CXX11))
     node = &TREE_TYPE (*node);
Index: c-family/c-pragma.c
===================================================================
--- c-family/c-pragma.c	(.../trunk/gcc)	(revision 228112)
+++ c-family/c-pragma.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -394,6 +394,51 @@ handle_pragma_weak (cpp_reader * ARG_UNU
     }
 }
 
+static enum scalar_storage_order_kind global_sso;
+
+void
+maybe_apply_pragma_scalar_storage_order (tree type)
+{
+  if (global_sso == SSO_NATIVE)
+    return;
+
+  gcc_assert (RECORD_OR_UNION_TYPE_P (type));
+
+  if (lookup_attribute ("scalar_storage_order", TYPE_ATTRIBUTES (type)))
+    return;
+
+  if (global_sso == SSO_BIG_ENDIAN)
+    TYPE_REVERSE_STORAGE_ORDER (type) = !BYTES_BIG_ENDIAN;
+  else if (global_sso == SSO_LITTLE_ENDIAN)
+    TYPE_REVERSE_STORAGE_ORDER (type) = BYTES_BIG_ENDIAN;
+  else
+    gcc_unreachable ();
+}
+
+static void
+handle_pragma_scalar_storage_order (cpp_reader *ARG_UNUSED(dummy))
+{
+  const char *kind_string;
+  enum cpp_ttype token;
+  tree x;
+
+  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+    error ("scalar_storage_order is not supported");
+
+  token = pragma_lex (&x);
+  if (token != CPP_NAME)
+    GCC_BAD ("missing [big-endian|little-endian|default] after %<#pragma scalar_storage_order%>");
+  kind_string = IDENTIFIER_POINTER (x);
+  if (strcmp (kind_string, "default") == 0)
+    global_sso = default_sso;
+  else if (strcmp (kind_string, "big") == 0)
+    global_sso = SSO_BIG_ENDIAN;
+  else if (strcmp (kind_string, "little") == 0)
+    global_sso = SSO_LITTLE_ENDIAN;
+  else
+    GCC_BAD ("expected [big-endian|little-endian|default] after %<#pragma scalar_storage_order%>");
+}
+
 /* GCC supports two #pragma directives for renaming the external
    symbol associated with a declaration (DECL_ASSEMBLER_NAME), for
    compatibility with the Solaris and VMS system headers.  GCC also
@@ -1485,6 +1530,7 @@ init_pragma (void)
   c_register_pragma (0, "pack", handle_pragma_pack);
 #endif
   c_register_pragma (0, "weak", handle_pragma_weak);
+
   c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
 
   c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
@@ -1506,6 +1552,10 @@ init_pragma (void)
   REGISTER_TARGET_PRAGMAS ();
 #endif
 
+  global_sso = default_sso;
+  c_register_pragma (0, "scalar_storage_order", 
+		     handle_pragma_scalar_storage_order);
+
   /* Allow plugins to register their own pragmas. */
   invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL);
 }
Index: c-family/c-pragma.h
===================================================================
--- c-family/c-pragma.h	(.../trunk/gcc)	(revision 228112)
+++ c-family/c-pragma.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -210,6 +210,7 @@ extern void c_invoke_pragma_handler (uns
 extern void maybe_apply_pragma_weak (tree);
 extern void maybe_apply_pending_pragma_weaks (void);
 extern tree maybe_apply_renaming_pragma (tree, tree);
+extern void maybe_apply_pragma_scalar_storage_order (tree);
 extern void add_to_renaming_pragma_list (tree, tree);
 
 extern enum cpp_ttype pragma_lex (tree *, location_t *loc = NULL);
Index: c/c-typeck.c
===================================================================
--- c/c-typeck.c	(.../trunk/gcc)	(revision 228112)
+++ c/c-typeck.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -4173,18 +4173,10 @@ build_unary_op (location_t location,
 	  goto return_build_unary_op;
 	}
 
-      /* For &x[y], return x+y */
-      if (TREE_CODE (arg) == ARRAY_REF)
-	{
-	  tree op0 = TREE_OPERAND (arg, 0);
-	  if (!c_mark_addressable (op0))
-	    return error_mark_node;
-	}
-
       /* Anything not already handled and not a true memory reference
 	 or a non-lvalue array is an error.  */
-      else if (typecode != FUNCTION_TYPE && !flag
-	       && !lvalue_or_else (location, arg, lv_addressof))
+      if (typecode != FUNCTION_TYPE && !flag
+	  && !lvalue_or_else (location, arg, lv_addressof))
 	return error_mark_node;
 
       /* Move address operations inside C_MAYBE_CONST_EXPR to simplify
@@ -4222,6 +4214,39 @@ build_unary_op (location_t location,
 	  argtype = c_build_qualified_type (argtype, quals);
 	}
 
+      switch (TREE_CODE (arg))
+	{
+	case COMPONENT_REF:
+	  if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
+	    {
+	      error ("cannot take address of bit-field %qD",
+		     TREE_OPERAND (arg, 1));
+	      return error_mark_node;
+	    }
+
+	  /* ... fall through ...  */
+
+	case ARRAY_REF:
+	  if (TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (arg, 0))))
+	    {
+	      if (!AGGREGATE_TYPE_P (TREE_TYPE (arg))
+		  && !VECTOR_TYPE_P (TREE_TYPE (arg)))
+		{
+		  error ("cannot take address of scalar with reverse storage "
+			 "order");
+		  return error_mark_node;
+		}
+
+	      if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE
+		  && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (arg)))
+		warning (OPT_Wscalar_storage_order, "address of array with "
+			"reverse scalar storage order requested");
+	    }
+
+	default:
+	  break;
+	}
+
       if (!c_mark_addressable (arg))
 	return error_mark_node;
 
@@ -4364,15 +4389,6 @@ c_mark_addressable (tree exp)
     switch (TREE_CODE (x))
       {
       case COMPONENT_REF:
-	if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
-	  {
-	    error
-	      ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1));
-	    return false;
-	  }
-
-	/* ... fall through ...  */
-
       case ADDR_EXPR:
       case ARRAY_REF:
       case REALPART_EXPR:
@@ -8423,7 +8439,11 @@ output_init_element (location_t loc, tre
     constructor_erroneous = 1;
   else if (!TREE_CONSTANT (value))
     constructor_constant = 0;
-  else if (!initializer_constant_valid_p (value, TREE_TYPE (value))
+  else if (!initializer_constant_valid_p (value,
+					  TREE_TYPE (value),
+					  AGGREGATE_TYPE_P (constructor_type)
+					  && TYPE_REVERSE_STORAGE_ORDER
+					     (constructor_type))
 	   || ((TREE_CODE (constructor_type) == RECORD_TYPE
 		|| TREE_CODE (constructor_type) == UNION_TYPE)
 	       && DECL_C_BIT_FIELD (field)
@@ -12661,6 +12681,12 @@ c_build_qualified_type (tree type, int t
                 = build_array_type (TYPE_CANONICAL (element_type),
                                     domain? TYPE_CANONICAL (domain)
                                           : NULL_TREE);
+              if (TYPE_REVERSE_STORAGE_ORDER (type))
+                {
+                  unqualified_canon
+                    = build_distinct_type_copy (unqualified_canon);
+                  TYPE_REVERSE_STORAGE_ORDER (unqualified_canon) = 1;
+                }
               TYPE_CANONICAL (t)
                 = c_build_qualified_type (unqualified_canon, type_quals);
             }
Index: c/c-decl.c
===================================================================
--- c/c-decl.c	(.../trunk/gcc)	(revision 228112)
+++ c/c-decl.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -7723,6 +7723,8 @@ finish_struct (location_t loc, tree t, t
 
   TYPE_FIELDS (t) = fieldlist;
 
+  maybe_apply_pragma_scalar_storage_order (t);
+
   layout_type (t);
 
   if (TYPE_SIZE_UNIT (t)
@@ -7731,27 +7733,45 @@ finish_struct (location_t loc, tree t, t
       && !valid_constant_size_p (TYPE_SIZE_UNIT (t)))
     error ("type %qT is too large", t);
 
-  /* Give bit-fields their proper types.  */
-  {
-    tree *fieldlistp = &fieldlist;
-    while (*fieldlistp)
-      if (TREE_CODE (*fieldlistp) == FIELD_DECL && DECL_INITIAL (*fieldlistp)
-	  && TREE_TYPE (*fieldlistp) != error_mark_node)
+  /* Give bit-fields their proper types and rewrite the type of array fields
+     with scalar component if the enclosing type has reverse storage order.  */
+  for (tree field = fieldlist; field; field = DECL_CHAIN (field))
+    {
+      if (TREE_CODE (field) == FIELD_DECL
+	  && DECL_INITIAL (field)
+	  && TREE_TYPE (field) != error_mark_node)
 	{
 	  unsigned HOST_WIDE_INT width
-	    = tree_to_uhwi (DECL_INITIAL (*fieldlistp));
-	  tree type = TREE_TYPE (*fieldlistp);
+	    = tree_to_uhwi (DECL_INITIAL (field));
+	  tree type = TREE_TYPE (field);
 	  if (width != TYPE_PRECISION (type))
 	    {
-	      TREE_TYPE (*fieldlistp)
+	      TREE_TYPE (field)
 		= c_build_bitfield_integer_type (width, TYPE_UNSIGNED (type));
-	      DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp));
+	      DECL_MODE (field) = TYPE_MODE (TREE_TYPE (field));
+	    }
+	  DECL_INITIAL (field) = 0;
+	}
+      else if (TYPE_REVERSE_STORAGE_ORDER (t)
+	       && TREE_CODE (field) == FIELD_DECL
+	       && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
+	{
+	  tree ftype = TREE_TYPE (field);
+	  tree ctype = strip_array_types (ftype);
+	  if (!RECORD_OR_UNION_TYPE_P (ctype) && TYPE_MODE (ctype) != QImode)
+	    {
+	      tree fmain_type = TYPE_MAIN_VARIANT (ftype);
+	      tree *typep = &fmain_type;
+	      do {
+		*typep = build_distinct_type_copy (*typep);
+		TYPE_REVERSE_STORAGE_ORDER (*typep) = 1;
+		typep = &TREE_TYPE (*typep);
+	      } while (TREE_CODE (*typep) == ARRAY_TYPE);
+	      TREE_TYPE (field)
+		= c_build_qualified_type (fmain_type, TYPE_QUALS (ftype));
 	    }
-	  DECL_INITIAL (*fieldlistp) = 0;
 	}
-      else
-	fieldlistp = &DECL_CHAIN (*fieldlistp);
-  }
+    }
 
   /* Now we have the truly final field list.
      Store it in this type and in the variants.  */

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [patch 3/6] scalar-storage-order merge: C++ front-end
  2015-10-06 10:57 [patch 0/6] scalar-storage-order merge (2) Eric Botcazou
  2015-10-06 11:01 ` [patch 1/6] scalar-storage-order merge: Ada front-end Eric Botcazou
  2015-10-06 11:02 ` [patch 2/6] scalar-storage-order merge: C front-end Eric Botcazou
@ 2015-10-06 11:03 ` Eric Botcazou
  2015-10-12 22:27   ` Jeff Law
  2015-10-06 11:05 ` [patch 4/6] scalar-storage-order merge: bulk Eric Botcazou
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 32+ messages in thread
From: Eric Botcazou @ 2015-10-06 11:03 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1055 bytes --]

This is the C++ front-end part, probably incomplete but passes the testsuite.

cp/
	* class.c: Add c-family/c-pragma.h.
	(finish_struct_1): If structure has reverse scalar storage order,
	rewrite the type of array fields with scalar component.  Call
	maybe_apply_pragma_scalar_storage_order on entry.
	* constexpr.c (reduced_constant_expression_p): Unfold recursion and
	deal with TYPE_REVERSE_STORAGE_ORDER.
	* typeck.c (structural_comptypes): Return false if two aggregate
	types have different scalar storage order.
	(cp_build_addr_expr_1) <case COMPONENT_REF>: New case.  Issue the
	error for bit-fields here and not later.
	<case ARRAY_REF>: Issue error and warning for reverse scalar storage
	order.
	* typeck2.c (split_nonconstant_init_1) <RECORD_TYPE>: Adjust call to
	initializer_constant_valid_p.

 class.c     |   24 +++++++++++++++++++++++-
 constexpr.c |   19 +++++++++++++++++--
 typeck.c    |   45 ++++++++++++++++++++++++++++++++++++++-------
 typeck2.c   |    5 ++++-
 4 files changed, 82 insertions(+), 11 deletions(-)

-- 
Eric Botcazou

[-- Attachment #2: sso-cpp.diff --]
[-- Type: text/x-patch, Size: 5838 bytes --]

Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(.../trunk/gcc)	(revision 228112)
+++ cp/typeck.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1217,6 +1217,9 @@ structural_comptypes (tree t1, tree t2,
     return false;
   if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
     return false;
+  if (AGGREGATE_TYPE_P (t1)
+      && TYPE_REVERSE_STORAGE_ORDER (t1) != TYPE_REVERSE_STORAGE_ORDER (t2))
+    return false;
 
   /* Allow for two different type nodes which have essentially the same
      definition.  Note that we already checked for equality of the type
@@ -5584,6 +5587,41 @@ cp_build_addr_expr_1 (tree arg, bool str
 	}
       break;
 
+    case COMPONENT_REF:
+      if (BASELINK_P (TREE_OPERAND (arg, 1)))
+	break;
+
+      if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
+	{
+	  if (complain & tf_error)
+	    error ("attempt to take address of bit-field structure member %qD",
+		   TREE_OPERAND (arg, 1));
+	  return error_mark_node;
+	}
+      /* Fall through.  */
+
+    case ARRAY_REF:
+      if (TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (arg, 0))))
+	{
+	  if (!AGGREGATE_TYPE_P (TREE_TYPE (arg))
+	      && !VECTOR_TYPE_P (TREE_TYPE (arg)))
+	    {
+	      if (complain & tf_error)
+		error ("attempt to take address of scalar with reverse "
+		       "storage order");
+	      return error_mark_node;
+	    }
+
+	   if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE
+	       && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (arg)))
+	    {
+	      if (complain & tf_warning)
+		warning (OPT_Wscalar_storage_order, "address of array with "
+			 "reverse scalar storage order requested");
+	    }
+	}
+      break;
+
     case BASELINK:
       arg = BASELINK_FUNCTIONS (arg);
       /* Fall through.  */
@@ -5647,13 +5685,6 @@ cp_build_addr_expr_1 (tree arg, bool str
 	val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
 		      TREE_OPERAND (arg, 0), val);
     }
-  else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
-    {
-      if (complain & tf_error)
-	error ("attempt to take address of bit-field structure member %qD",
-	       TREE_OPERAND (arg, 1));
-      return error_mark_node;
-    }
   else
     {
       tree object = TREE_OPERAND (arg, 0);
Index: cp/class.c
===================================================================
--- cp/class.c	(.../trunk/gcc)	(revision 228112)
+++ cp/class.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.
 #include "stor-layout.h"
 #include "attribs.h"
 #include "cp-tree.h"
+#include "c-family/c-pragma.h"
 #include "flags.h"
 #include "toplev.h"
 #include "target.h"
@@ -6625,6 +6626,7 @@ finish_struct_1 (tree t)
     }
 
   /* Layout the class itself.  */
+  maybe_apply_pragma_scalar_storage_order (t);
   layout_class_type (t, &virtuals);
   if (CLASSTYPE_AS_BASE (t) != t)
     /* We use the base type for trivial assignments, and hence it
@@ -6688,12 +6690,32 @@ finish_struct_1 (tree t)
   set_method_tm_attributes (t);
 
   /* Complete the rtl for any static member objects of the type we're
-     working on.  */
+     working on and rewrite the type of array fields with scalar
+     component if the enclosing type has reverse storage order.  */
   for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
     if (VAR_P (x) && TREE_STATIC (x)
         && TREE_TYPE (x) != error_mark_node
 	&& same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))
       DECL_MODE (x) = TYPE_MODE (t);
+    else if (TYPE_REVERSE_STORAGE_ORDER (t)
+	     && TREE_CODE (x) == FIELD_DECL
+	     && TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
+      {
+	tree ftype = TREE_TYPE (x);
+	tree ctype = strip_array_types (ftype);
+	if (!RECORD_OR_UNION_TYPE_P (ctype) && TYPE_MODE (ctype) != QImode)
+	  {
+	    tree fmain_type = TYPE_MAIN_VARIANT (ftype);
+	    tree *typep = &fmain_type;
+	    do {
+	      *typep = build_distinct_type_copy (*typep);
+	      TYPE_REVERSE_STORAGE_ORDER (*typep) = 1;
+	      typep = &TREE_TYPE (*typep);
+	    } while (TREE_CODE (*typep) == ARRAY_TYPE);
+	    TREE_TYPE (x)
+	      = cp_build_qualified_type (fmain_type, TYPE_QUALS (ftype));
+	  }
+      }
 
   /* Done with FIELDS...now decide whether to sort these for
      faster lookups later.
Index: cp/constexpr.c
===================================================================
--- cp/constexpr.c	(.../trunk/gcc)	(revision 228112)
+++ cp/constexpr.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1439,8 +1439,23 @@ reduced_constant_expression_p (tree t)
       /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR.  */
       tree elt; unsigned HOST_WIDE_INT idx;
       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, elt)
-	if (!reduced_constant_expression_p (elt))
-	  return false;
+	switch (TREE_CODE (elt))
+	  {
+	  case PTRMEM_CST:
+	    break;
+	  case CONSTRUCTOR:
+	    if (!reduced_constant_expression_p (elt))
+	      return false;
+	    break;
+	  default:
+	    if (!initializer_constant_valid_p (elt,
+					       TREE_TYPE (elt),
+					       !VECTOR_TYPE_P (TREE_TYPE (t))
+					       && TYPE_REVERSE_STORAGE_ORDER
+						  (TREE_TYPE (t))))
+	      return false;
+	    break;
+	  }
       return true;
 
     default:
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c	(.../trunk/gcc)	(revision 228112)
+++ cp/typeck2.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -648,7 +648,10 @@ split_nonconstant_init_1 (tree dest, tre
 		CONSTRUCTOR_ELTS (init)->ordered_remove (idx--);
 	      num_split_elts++;
 	    }
-	  else if (!initializer_constant_valid_p (value, inner_type))
+	  else if (!initializer_constant_valid_p (value,
+						  inner_type,
+						  TYPE_REVERSE_STORAGE_ORDER
+						  (type)))
 	    {
 	      tree code;
 	      tree sub;

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [patch 4/6] scalar-storage-order merge: bulk
  2015-10-06 10:57 [patch 0/6] scalar-storage-order merge (2) Eric Botcazou
                   ` (2 preceding siblings ...)
  2015-10-06 11:03 ` [patch 3/6] scalar-storage-order merge: C++ front-end Eric Botcazou
@ 2015-10-06 11:05 ` Eric Botcazou
  2015-10-13 16:07   ` Jeff Law
  2015-10-06 11:06 ` [patch 5/6] scalar-storage-order merge: rest Eric Botcazou
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 32+ messages in thread
From: Eric Botcazou @ 2015-10-06 11:05 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 9206 bytes --]

This is the bulk of the implementation.

	* calls.c (store_unaligned_arguments_into_pseudos): Adjust calls to
	extract_bit_field and store_bit_field.
	(initialize_argument_information): Adjust call to store_expr.
	(load_register_parameters): Adjust call to extract_bit_field.
	* expmed.c (check_reverse_storage_order_support): New function.
	(check_reverse_float_storage_order_support): Likewise.
	(flip_storage_order): Likewise.
	(store_bit_field_1): Add REVERSE parameter.  Flip the storage order
	of the value if it is true.  Pass REVERSE to recursive call after
	adjusting the target offset.
	Do not use extraction or movstrict instruction if REVERSE is true.
	Pass REVERSE to store_fixed_bit_field.
	(store_bit_field): Add REVERSE parameter and pass to it to above.
	(store_fixed_bit_field): Add REVERSE parameter and pass to it to
	store_split_bit_field and store_fixed_bit_field_1.
	(store_fixed_bit_field_1):  Add REVERSE parameter.  Flip the storage
	order of the value if it is true and adjust the target offset.
	(store_split_bit_field): Add REVERSE parameter and pass it to
	store_fixed_bit_field.  Adjust the target offset if it is true.
	(extract_bit_field_1): Add REVERSE parameter.  Flip the storage order
	of the value if it is true.  Pass REVERSE to recursive call after
	adjusting the target offset.
	Do not use extraction or subreg instruction if REVERSE is true.
	Pass REVERSE to extract_fixed_bit_field.
	(extract_bit_field): Add REVERSE parameter and pass to it to above.
	(extract_fixed_bit_field): Add REVERSE parameter and pass to it to
	extract_split_bit_field and extract_fixed_bit_field_1.
	(extract_fixed_bit_field_1): Add REVERSE parameter.  Flip the storage
	order of the value if it is true and adjust the target offset.
	(extract_split_bit_field): Add REVERSE parameter and pass it to
	extract_fixed_bit_field.  Adjust the target offset if it is true.
	* expmed.h (flip_storage_order): Declare.
	(store_bit_field): Adjust prototype.
	(extract_bit_field): Likewise.
	* expr.c (emit_group_load_1): Adjust calls to extract_bit_field.
	(emit_group_store): Adjust call to store_bit_field.
	(copy_blkmode_from_reg): Likewise.
	(copy_blkmode_to_reg): Likewise.
	(write_complex_part): Likewise.
 	(read_complex_part): Likewise.
	(optimize_bitfield_assignment_op): Add REVERSE parameter.  Assert
	that it isn't true if the target is a register.
	<PLUS_EXPR>: If it is, do not optimize unless bitsize is equal to 1,
	and flip the storage order of the value.
	<BIT_IOR_EXPR>: Flip the storage order of the value.
	(get_bit_range): Adjust call to get_inner_reference.
	(expand_assignment): Adjust calls to get_inner_reference, store_expr,
	optimize_bitfield_assignment_op and store_field.  Handle MEM_EXPRs
	with reverse storage order.
	(store_expr_with_bounds): Add REVERSE parameter and pass it to
	recursive calls and call to store_bit_field.  Force the value into a
	register if it is true and then flip the storage order of the value.
	(store_expr): Add REVERSE parameter and pass it to above.
	(categorize_ctor_elements_1): Adjust call to
	initializer_constant_valid_p.
	(store_constructor_field): Add REVERSE parameter and pass it to
	recursive calls and call to store_field.
	(store_constructor): Add REVERSE parameter and pass it to calls to
	store_constructor_field and store_expr.  Set it to true for an
	aggregate type with TYPE_REVERSE_STORAGE_ORDER.
	(store_field): Add REVERSE parameter and pass it to recursive calls
	and calls to store_expr and store_bit_field.  Temporarily flip the
	storage order of the value with record type and integral mode and
	adjust the shift if it is true.
	(get_inner_reference): Add PREVERSEP parameter and set it to true
	upon encoutering a reference with reverse storage order.
	(expand_expr_addr_expr_1): Adjust call to get_inner_reference.
	(expand_constructor): Adjust call to store_constructor.
	(expand_expr_real_2) <CASE_CONVERT>: Pass TYPE_REVERSE_STORAGE_ORDER
	of the union type to store_expr in the MEM case and assert that it
	isn't set in the REG case.  Adjust call to store_field.
	(expand_expr_real_1) <MEM_REF>: Handle reverse storage order.
	<normal_inner_ref>: Add REVERSEP variable and adjust calls to
	get_inner_reference and extract_bit_field. Temporarily flip the
	storage order of the value with record type and integral mode and
	adjust the shift if it is true.  Flip the storage order of the value
	at the end if it is true.
	<VIEW_CONVERT_EXPR>: Add REVERSEP variable and adjust call to
	get_inner_reference.  Do not fetch an inner reference if it is true.
	* expr.h (store_expr_with_bounds): Ajust prototype.
	(store_expr): Likewise.
	* fold-const.c (make_bit_field_ref): Add REVERSEP parameter and set
	REF_REVERSE_STORAGE_ORDER on the reference according to it.
	(optimize_bit_field_compare): Deal with reverse storage order.
	Adjust calls to get_inner_reference and make_bit_field_ref.
	(decode_field_reference): Add PREVERSEP parameter and adjust call to
	get_inner_reference.
	(fold_truth_andor_1): Deal with reverse storage order.  Adjust calls
	to decode_field_reference and make_bit_field_ref.
	(fold_unary_loc) <CASE_CONVERT>: Adjust call to get_inner_reference.
	<VIEW_CONVERT_EXPR>: Propagate the REF_REVERSE_STORAGE_ORDER flag.
	(fold_comparison): Adjust call to get_inner_reference.
	(split_address_to_core_and_offset): Adjust call to
	get_inner_reference.
	* gimple-expr.c (useless_type_conversion_p): Return false for array
	types with different TYPE_REVERSE_STORAGE_ORDER flag.
	* gimplify.c (gimplify_expr) <MEM_REF>: Propagate the
	REF_REVERSE_STORAGE_ORDER flag.
	* lto-streamer-out.c (hash_tree): Deal with
	TYPE_REVERSE_STORAGE_ORDER.
	* output.h (assemble_real): Adjust prototype.
	* print-tree.c (print_node): Convey TYPE_REVERSE_STORAGE_ORDER.
	* stor-layout.c (finish_record_layout): Propagate the
	TYPE_REVERSE_STORAGE_ORDER flag to the variants.
	* tree-core.h (TYPE_REVERSE_STORAGE_ORDER): Document.
	(TYPE_SATURATING): Adjust.
	(REF_REVERSE_STORAGE_ORDER): Document.
	* tree-dfa.c (get_ref_base_and_extent): Add PREVERSE parameter and
	set it to true upon encoutering a reference with reverse storage
	order.
	* tree-dfa.h (get_ref_base_and_extent): Adjust prototype.
	* tree-inline.c (remap_gimple_op_r): Propagate the
	REF_REVERSE_STORAGE_ORDER flag.
	(copy_tree_body_r): Likewise.
	* tree-outof-ssa.c (insert_value_copy_on_edge): Adjust call to
	store_expr.
	* tree-streamer-in.c (unpack_ts_base_value_fields): Deal with
	TYPE_REVERSE_STORAGE_ORDER and REF_REVERSE_STORAGE_ORDER.
	* tree-streamer-out.c (pack_ts_base_value_fields): Likewise.
	* tree.c (stabilize_reference) <BIT_FIELD_REF>: Propagate the
	REF_REVERSE_STORAGE_ORDER flag.
	(verify_type_variant): Deal with TYPE_REVERSE_STORAGE_ORDER.
	(gimple_canonical_types_compatible_p): Likewise.
	* tree.h (TYPE_REVERSE_STORAGE_ORDER): New flag.
	(TYPE_SATURATING): Adjust.
	(REF_REVERSE_STORAGE_ORDER): New flag.
	(reverse_storage_order_for_component_p): New inline predicate.
 	(storage_order_barrier_p): Likewise.
	(get_inner_reference): Adjust prototype.
	* varasm.c (assemble_real): Add REVERSE parameter.  Flip the storage
	order of the value if REVERSE is true.
	(compare_constant) <CONSTRUCTOR>: Compare TYPE_REVERSE_STORAGE_ORDER.
	(assemble_constant_contents): Adjust call to output_constant.
	(output_constant_pool_2): Adjust call to assemble_real.
	(initializer_constant_valid_p_1) <CONSTRUCTOR>: Deal with
	TYPE_REVERSE_STORAGE_ORDER.
	(output_constant): Add REVERSE parameter.
	<INTEGER_TYPE>: Flip the storage order of the value if REVERSE is
	true.
	<REAL_TYPE>: Adjust call to assemble_real.
	<COMPLEX_TYPE>: Pass it to recursive calls.
	<ARRAY_TYPE>: Likewise.  Adjust call to output_constructor.
	<RECORD_TYPE>: Likewise.  Adjust call to output_constructor.
	(struct oc_local_state): Add REVERSE field.
	(output_constructor_array_range): Adjust calls to output_constant.
	(output_constructor_regular_field): Likewise.
	(output_constructor_bitfield): Adjust call to output_constructor.
	Flip the storage order of the value if REVERSE is true.
	(output_constructor): Add REVERSE parameter.  Set it to true for an
	aggregate type with TYPE_REVERSE_STORAGE_ORDER.  Adjust call to
	output_constructor_bitfield.
lto/
	* lto.c (compare_tree_sccs_1): Deal with TYPE_REVERSE_STORAGE_ORDER.

 calls.c             |   10 -
 expmed.c            |  262 +++++++++++++++++++++++++++++++++---------
 expmed.h            |    8 -
 expr.c              |  324 +++++++++++++++++++++++++++++++-------------------
 expr.h              |    5 
 fold-const.c        |  132 ++++++++++++---------
 gimple-expr.c       |    8 -
 gimplify.c          |    2 
 lto-streamer-out.c  |    3 
 lto/lto.c           |    5 
 output.h            |    2 
 print-tree.c        |    7 +
 stor-layout.c       |   11 +
 tree-core.h         |    8 +
 tree-dfa.c          |   11 +
 tree-dfa.h          |    2 
 tree-inline.c       |    2 
 tree-outof-ssa.c    |    2 
 tree-streamer-in.c  |    7 -
 tree-streamer-out.c |    7 -
 tree.c              |   10 +
 tree.h              |   85 +++++++++++++
 varasm.c            |  117 +++++++++++++-----
 varasm.h            |    2 
 24 files changed, 742 insertions(+), 290 deletions(-)

-- 
Eric Botcazou

[-- Attachment #2: sso-bulk.diff --]
[-- Type: text/x-patch, Size: 108699 bytes --]

Index: tree.c
===================================================================
--- tree.c	(.../trunk/gcc)	(revision 228112)
+++ tree.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -4166,6 +4166,7 @@ stabilize_reference (tree ref)
       result = build_nt (BIT_FIELD_REF,
 			 stabilize_reference (TREE_OPERAND (ref, 0)),
 			 TREE_OPERAND (ref, 1), TREE_OPERAND (ref, 2));
+      REF_REVERSE_STORAGE_ORDER (result) = REF_REVERSE_STORAGE_ORDER (ref);
       break;
 
     case ARRAY_REF:
@@ -12814,7 +12815,10 @@ verify_type_variant (const_tree t, tree
   verify_variant_match (TYPE_PACKED);
   if (TREE_CODE (t) == REFERENCE_TYPE)
     verify_variant_match (TYPE_REF_IS_RVALUE);
-  verify_variant_match (TYPE_SATURATING);
+  if (AGGREGATE_TYPE_P (t))
+    verify_variant_match (TYPE_REVERSE_STORAGE_ORDER);
+  else
+    verify_variant_match (TYPE_SATURATING);
   /* FIXME: This check trigger during libstdc++ build.  */
   if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t) && 0)
     verify_variant_match (TYPE_FINAL_P);
@@ -13114,6 +13118,7 @@ gimple_canonical_types_compatible_p (con
       if (!gimple_canonical_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
 						trust_type_canonical)
 	  || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)
+	  || TYPE_REVERSE_STORAGE_ORDER (t1) != TYPE_REVERSE_STORAGE_ORDER (t2)
 	  || TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2))
 	return false;
       else
@@ -13187,6 +13192,9 @@ gimple_canonical_types_compatible_p (con
       {
 	tree f1, f2;
 
+	if (TYPE_REVERSE_STORAGE_ORDER (t1) != TYPE_REVERSE_STORAGE_ORDER (t2))
+	  return false;
+
 	/* For aggregate types, all the fields must be the same.  */
 	for (f1 = TYPE_FIELDS (t1), f2 = TYPE_FIELDS (t2);
 	     f1 || f2;
Index: tree.h
===================================================================
--- tree.h	(.../trunk/gcc)	(revision 228112)
+++ tree.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -896,8 +896,29 @@ extern void omp_clause_range_check_faile
 #define IDENTIFIER_TRANSPARENT_ALIAS(NODE) \
   (IDENTIFIER_NODE_CHECK (NODE)->base.deprecated_flag)
 
-/* In fixed-point types, means a saturating type.  */
-#define TYPE_SATURATING(NODE) (TYPE_CHECK (NODE)->base.u.bits.saturating_flag)
+/* In an aggregate type, indicates that the scalar fields of the type are
+   stored in reverse order from the target order.  This effectively
+   toggles BYTES_BIG_ENDIAN and WORDS_BIG_ENDIAN within the type.  */
+#define TYPE_REVERSE_STORAGE_ORDER(NODE) \
+  (TREE_CHECK4 (NODE, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, ARRAY_TYPE)->base.u.bits.saturating_flag)
+
+/* In a non-aggregate type, indicates a saturating type.  */
+#define TYPE_SATURATING(NODE) \
+  (TREE_NOT_CHECK4 (NODE, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, ARRAY_TYPE)->base.u.bits.saturating_flag)
+
+/* In a BIT_FIELD_REF and MEM_REF, indicates that the reference is to a group
+   of bits stored in reverse order from the target order.  This effectively
+   toggles both BYTES_BIG_ENDIAN and WORDS_BIG_ENDIAN for the reference.
+
+   The overall strategy is to preserve the invariant that every scalar in
+   memory is associated with a single storage order, i.e. all accesses to
+   this scalar are done with the same storage order.  This invariant makes
+   it possible to factor out the storage order in most transformations, as
+   only the address and/or the value (in target order) matter for them.
+   But, of course, the storage order must be preserved when the accesses
+   themselves are rewritten or transformed.  */
+#define REF_REVERSE_STORAGE_ORDER(NODE) \
+  (TREE_CHECK2 (NODE, BIT_FIELD_REF, MEM_REF)->base.u.bits.saturating_flag)
 
 /* These flags are available for each language front end to use internally.  */
 #define TREE_LANG_FLAG_0(NODE) \
@@ -4288,6 +4309,64 @@ handled_component_p (const_tree t)
     }
 }
 
+/* Return true T is a component with reverse storage order.  */
+
+static inline bool
+reverse_storage_order_for_component_p (tree t)
+{
+  /* The storage order only applies to scalar components.  */
+  if (AGGREGATE_TYPE_P (TREE_TYPE (t)) || VECTOR_TYPE_P (TREE_TYPE (t)))
+    return false;
+
+  if (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR)
+    t = TREE_OPERAND (t, 0);
+
+  switch (TREE_CODE (t))
+    {
+    case ARRAY_REF:
+    case COMPONENT_REF:
+      /* ??? Fortran can take COMPONENT_REF of a void type.  */
+      return !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))
+	     && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (t, 0)));
+
+    case BIT_FIELD_REF:
+    case MEM_REF:
+      return REF_REVERSE_STORAGE_ORDER (t);
+
+    case ARRAY_RANGE_REF:
+    case VIEW_CONVERT_EXPR:
+    default:
+      return false;
+    }
+
+  gcc_unreachable ();
+}
+
+/* Return true if T is a storage order barrier, i.e. a VIEW_CONVERT_EXPR
+   that can modify the storage order of objects.  Note that, even if the
+   TYPE_REVERSE_STORAGE_ORDER flag is set on both the inner type and the
+   outer type, a VIEW_CONVERT_EXPR can modify the storage order because
+   it can change the partition of the aggregate object into scalars.  */
+
+static inline bool
+storage_order_barrier_p (const_tree t)
+{
+  if (TREE_CODE (t) != VIEW_CONVERT_EXPR)
+    return false;
+
+  if (AGGREGATE_TYPE_P (TREE_TYPE (t))
+      && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (t)))
+    return true;
+
+  tree op = TREE_OPERAND (t, 0);
+
+  if (AGGREGATE_TYPE_P (TREE_TYPE (op))
+      && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (op)))
+    return true;
+
+  return false;
+}
+
 /* Given a DECL or TYPE, return the scope in which it was declared, or
    NUL_TREE if there is no containing scope.  */
 
@@ -5088,7 +5167,7 @@ extern bool complete_ctor_at_level_p (co
    the access position and size.  */
 extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
 				 tree *, machine_mode *, int *, int *,
-				 bool);
+				 int *, bool);
 
 extern tree build_personality_function (const char *);
 
Index: fold-const.c
===================================================================
--- fold-const.c	(.../trunk/gcc)	(revision 228112)
+++ fold-const.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -119,12 +119,12 @@ static int operand_equal_for_comparison_
 static int twoval_comparison_p (tree, tree *, tree *, int *);
 static tree eval_subst (location_t, tree, tree, tree, tree, tree);
 static tree make_bit_field_ref (location_t, tree, tree,
-				HOST_WIDE_INT, HOST_WIDE_INT, int);
+				HOST_WIDE_INT, HOST_WIDE_INT, int, int);
 static tree optimize_bit_field_compare (location_t, enum tree_code,
 					tree, tree, tree);
 static tree decode_field_reference (location_t, tree, HOST_WIDE_INT *,
 				    HOST_WIDE_INT *,
-				    machine_mode *, int *, int *,
+				    machine_mode *, int *, int *, int *,
 				    tree *, tree *);
 static int simple_operand_p (const_tree);
 static bool simple_operand_p_2 (tree);
@@ -3614,15 +3614,17 @@ distribute_real_division (location_t loc
 }
 \f
 /* Return a BIT_FIELD_REF of type TYPE to refer to BITSIZE bits of INNER
-   starting at BITPOS.  The field is unsigned if UNSIGNEDP is nonzero.  */
+   starting at BITPOS.  The field is unsigned if UNSIGNEDP is nonzero
+   and uses reverse storage order if REVERSEP is nonzero.  */
 
 static tree
 make_bit_field_ref (location_t loc, tree inner, tree type,
-		    HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, int unsignedp)
+		    HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
+		    int unsignedp, int reversep)
 {
   tree result, bftype;
 
-  if (bitpos == 0)
+  if (bitpos == 0 && !reversep)
     {
       tree size = TYPE_SIZE (TREE_TYPE (inner));
       if ((INTEGRAL_TYPE_P (TREE_TYPE (inner))
@@ -3639,6 +3641,7 @@ make_bit_field_ref (location_t loc, tree
 
   result = build3_loc (loc, BIT_FIELD_REF, bftype, inner,
 		       size_int (bitsize), bitsize_int (bitpos));
+  REF_REVERSE_STORAGE_ORDER (result) = reversep;
 
   if (bftype != type)
     result = fold_convert_loc (loc, type, result);
@@ -3676,6 +3679,7 @@ optimize_bit_field_compare (location_t l
   int const_p = TREE_CODE (rhs) == INTEGER_CST;
   machine_mode lmode, rmode, nmode;
   int lunsignedp, runsignedp;
+  int lreversep, rreversep;
   int lvolatilep = 0, rvolatilep = 0;
   tree linner, rinner = NULL_TREE;
   tree mask;
@@ -3687,20 +3691,23 @@ optimize_bit_field_compare (location_t l
      do anything if the inner expression is a PLACEHOLDER_EXPR since we
      then will no longer be able to replace it.  */
   linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode,
-				&lunsignedp, &lvolatilep, false);
+				&lunsignedp, &lreversep, &lvolatilep, false);
   if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0
       || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR || lvolatilep)
     return 0;
 
- if (!const_p)
+  if (const_p)
+    rreversep = lreversep;
+  else
    {
      /* If this is not a constant, we can only do something if bit positions,
-	sizes, and signedness are the same.  */
-     rinner = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode,
-				   &runsignedp, &rvolatilep, false);
+	sizes, signedness and storage order are the same.  */
+     rinner
+       = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode,
+			      &runsignedp, &rreversep, &rvolatilep, false);
 
      if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize
-	 || lunsignedp != runsignedp || offset != 0
+	 || lunsignedp != runsignedp || lreversep != rreversep || offset != 0
 	 || TREE_CODE (rinner) == PLACEHOLDER_EXPR || rvolatilep)
        return 0;
    }
@@ -3728,7 +3735,7 @@ optimize_bit_field_compare (location_t l
   if (nbitsize == lbitsize)
     return 0;
 
-  if (BYTES_BIG_ENDIAN)
+  if (lreversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
     lbitpos = nbitsize - lbitsize - lbitpos;
 
   /* Make the mask to be used against the extracted field.  */
@@ -3745,17 +3752,17 @@ optimize_bit_field_compare (location_t l
 				     make_bit_field_ref (loc, linner,
 							 unsigned_type,
 							 nbitsize, nbitpos,
-							 1),
+							 1, lreversep),
 				     mask),
 			fold_build2_loc (loc, BIT_AND_EXPR, unsigned_type,
 				     make_bit_field_ref (loc, rinner,
 							 unsigned_type,
 							 nbitsize, nbitpos,
-							 1),
+							 1, rreversep),
 				     mask));
 
-  /* Otherwise, we are handling the constant case. See if the constant is too
-     big for the field.  Warn and return a tree of for 0 (false) if so.  We do
+  /* Otherwise, we are handling the constant case.  See if the constant is too
+     big for the field.  Warn and return a tree for 0 (false) if so.  We do
      this not only for its own sake, but to avoid having to test for this
      error case below.  If we didn't, we might generate wrong code.
 
@@ -3793,7 +3800,8 @@ optimize_bit_field_compare (location_t l
   /* Make a new bitfield reference, shift the constant over the
      appropriate number of bits and mask it with the computed mask
      (in case this was a signed field).  If we changed it, make a new one.  */
-  lhs = make_bit_field_ref (loc, linner, unsigned_type, nbitsize, nbitpos, 1);
+  lhs = make_bit_field_ref (loc, linner, unsigned_type, nbitsize, nbitpos, 1,
+			    lreversep);
 
   rhs = const_binop (BIT_AND_EXPR,
 		     const_binop (LSHIFT_EXPR,
@@ -3821,6 +3829,8 @@ optimize_bit_field_compare (location_t l
 
    *PUNSIGNEDP is set to the signedness of the field.
 
+   *PREVERSEP is set to the storage order of the field.
+
    *PMASK is set to the mask used.  This is either contained in a
    BIT_AND_EXPR or derived from the width of the field.
 
@@ -3832,7 +3842,7 @@ optimize_bit_field_compare (location_t l
 static tree
 decode_field_reference (location_t loc, tree exp, HOST_WIDE_INT *pbitsize,
 			HOST_WIDE_INT *pbitpos, machine_mode *pmode,
-			int *punsignedp, int *pvolatilep,
+			int *punsignedp, int *preversep, int *pvolatilep,
 			tree *pmask, tree *pand_mask)
 {
   tree outer_type = 0;
@@ -3865,7 +3875,7 @@ decode_field_reference (location_t loc,
     }
 
   inner = get_inner_reference (exp, pbitsize, pbitpos, &offset, pmode,
-			       punsignedp, pvolatilep, false);
+			       punsignedp, preversep, pvolatilep, false);
   if ((inner == exp && and_mask == 0)
       || *pbitsize < 0 || offset != 0
       || TREE_CODE (inner) == PLACEHOLDER_EXPR)
@@ -5369,6 +5379,7 @@ fold_truth_andor_1 (location_t loc, enum
   HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
   HOST_WIDE_INT lnbitsize, lnbitpos, rnbitsize, rnbitpos;
   int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
+  int ll_reversep, lr_reversep, rl_reversep, rr_reversep;
   machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
   machine_mode lnmode, rnmode;
   tree ll_mask, lr_mask, rl_mask, rr_mask;
@@ -5481,33 +5492,39 @@ fold_truth_andor_1 (location_t loc, enum
   volatilep = 0;
   ll_inner = decode_field_reference (loc, ll_arg,
 				     &ll_bitsize, &ll_bitpos, &ll_mode,
-				     &ll_unsignedp, &volatilep, &ll_mask,
-				     &ll_and_mask);
+				     &ll_unsignedp, &ll_reversep, &volatilep,
+				     &ll_mask, &ll_and_mask);
   lr_inner = decode_field_reference (loc, lr_arg,
 				     &lr_bitsize, &lr_bitpos, &lr_mode,
-				     &lr_unsignedp, &volatilep, &lr_mask,
-				     &lr_and_mask);
+				     &lr_unsignedp, &lr_reversep, &volatilep,
+				     &lr_mask, &lr_and_mask);
   rl_inner = decode_field_reference (loc, rl_arg,
 				     &rl_bitsize, &rl_bitpos, &rl_mode,
-				     &rl_unsignedp, &volatilep, &rl_mask,
-				     &rl_and_mask);
+				     &rl_unsignedp, &rl_reversep, &volatilep,
+				     &rl_mask, &rl_and_mask);
   rr_inner = decode_field_reference (loc, rr_arg,
 				     &rr_bitsize, &rr_bitpos, &rr_mode,
-				     &rr_unsignedp, &volatilep, &rr_mask,
-				     &rr_and_mask);
+				     &rr_unsignedp, &rr_reversep, &volatilep,
+				     &rr_mask, &rr_and_mask);
 
   /* It must be true that the inner operation on the lhs of each
      comparison must be the same if we are to be able to do anything.
      Then see if we have constants.  If not, the same must be true for
      the rhs's.  */
-  if (volatilep || ll_inner == 0 || rl_inner == 0
+  if (volatilep
+      || ll_reversep != rl_reversep
+      || ll_inner == 0 || rl_inner == 0
       || ! operand_equal_p (ll_inner, rl_inner, 0))
     return 0;
 
   if (TREE_CODE (lr_arg) == INTEGER_CST
       && TREE_CODE (rr_arg) == INTEGER_CST)
-    l_const = lr_arg, r_const = rr_arg;
-  else if (lr_inner == 0 || rr_inner == 0
+    {
+      l_const = lr_arg, r_const = rr_arg;
+      lr_reversep = ll_reversep;
+    }
+  else if (lr_reversep != rr_reversep
+	   || lr_inner == 0 || rr_inner == 0
 	   || ! operand_equal_p (lr_inner, rr_inner, 0))
     return 0;
   else
@@ -5560,7 +5577,7 @@ fold_truth_andor_1 (location_t loc, enum
   lntype = lang_hooks.types.type_for_size (lnbitsize, 1);
   xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
 
-  if (BYTES_BIG_ENDIAN)
+  if (ll_reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
     {
       xll_bitpos = lnbitsize - xll_bitpos - ll_bitsize;
       xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
@@ -5625,7 +5642,7 @@ fold_truth_andor_1 (location_t loc, enum
       rntype = lang_hooks.types.type_for_size (rnbitsize, 1);
       xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
 
-      if (BYTES_BIG_ENDIAN)
+      if (lr_reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
 	{
 	  xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
 	  xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
@@ -5648,12 +5665,12 @@ fold_truth_andor_1 (location_t loc, enum
       if (lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos)
 	{
 	  lhs = make_bit_field_ref (loc, ll_inner, lntype, lnbitsize, lnbitpos,
-				    ll_unsignedp || rl_unsignedp);
+				    ll_unsignedp || rl_unsignedp, ll_reversep);
 	  if (! all_ones_mask_p (ll_mask, lnbitsize))
 	    lhs = build2 (BIT_AND_EXPR, lntype, lhs, ll_mask);
 
 	  rhs = make_bit_field_ref (loc, lr_inner, rntype, rnbitsize, rnbitpos,
-				    lr_unsignedp || rr_unsignedp);
+				    lr_unsignedp || rr_unsignedp, lr_reversep);
 	  if (! all_ones_mask_p (lr_mask, rnbitsize))
 	    rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask);
 
@@ -5676,10 +5693,12 @@ fold_truth_andor_1 (location_t loc, enum
 
 	  lhs = make_bit_field_ref (loc, ll_inner, lntype,
 				    ll_bitsize + rl_bitsize,
-				    MIN (ll_bitpos, rl_bitpos), ll_unsignedp);
+				    MIN (ll_bitpos, rl_bitpos),
+				    ll_unsignedp, ll_reversep);
 	  rhs = make_bit_field_ref (loc, lr_inner, rntype,
 				    lr_bitsize + rr_bitsize,
-				    MIN (lr_bitpos, rr_bitpos), lr_unsignedp);
+				    MIN (lr_bitpos, rr_bitpos),
+				    lr_unsignedp, lr_reversep);
 
 	  ll_mask = const_binop (RSHIFT_EXPR, ll_mask,
 				 size_int (MIN (xll_bitpos, xrl_bitpos)));
@@ -5742,7 +5761,7 @@ fold_truth_andor_1 (location_t loc, enum
      that field, perform the mask operation.  Then compare with the
      merged constant.  */
   result = make_bit_field_ref (loc, ll_inner, lntype, lnbitsize, lnbitpos,
-			       ll_unsignedp || rl_unsignedp);
+			       ll_unsignedp || rl_unsignedp, ll_reversep);
 
   ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask);
   if (! all_ones_mask_p (ll_mask, lnbitsize))
@@ -7597,10 +7616,11 @@ fold_unary_loc (location_t loc, enum tre
 	  HOST_WIDE_INT bitsize, bitpos;
 	  tree offset;
 	  machine_mode mode;
-	  int unsignedp, volatilep;
-          tree base = TREE_OPERAND (op0, 0);
-	  base = get_inner_reference (base, &bitsize, &bitpos, &offset,
-				      &mode, &unsignedp, &volatilep, false);
+	  int unsignedp, reversep, volatilep;
+	  tree base
+	    = get_inner_reference (TREE_OPERAND (op0, 0), &bitsize, &bitpos,
+				   &offset, &mode, &unsignedp, &reversep,
+				   &volatilep, false);
 	  /* If the reference was to a (constant) zero offset, we can use
 	     the address of the base if it has the same base type
 	     as the result type and the pointer type is unqualified.  */
@@ -7739,8 +7759,12 @@ fold_unary_loc (location_t loc, enum tre
 
     case VIEW_CONVERT_EXPR:
       if (TREE_CODE (op0) == MEM_REF)
-	return fold_build2_loc (loc, MEM_REF, type,
-				TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1));
+        {
+	  tem = fold_build2_loc (loc, MEM_REF, type,
+				 TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1));
+	  REF_REVERSE_STORAGE_ORDER (tem) = REF_REVERSE_STORAGE_ORDER (op0);
+	  return tem;
+	}
 
       return NULL_TREE;
 
@@ -8309,7 +8333,7 @@ fold_comparison (location_t loc, enum tr
       tree base0, base1, offset0 = NULL_TREE, offset1 = NULL_TREE;
       HOST_WIDE_INT bitsize, bitpos0 = 0, bitpos1 = 0;
       machine_mode mode;
-      int volatilep, unsignedp;
+      int volatilep, reversep, unsignedp;
       bool indirect_base0 = false, indirect_base1 = false;
 
       /* Get base and offset for the access.  Strip ADDR_EXPR for
@@ -8319,9 +8343,10 @@ fold_comparison (location_t loc, enum tr
       base0 = arg0;
       if (TREE_CODE (arg0) == ADDR_EXPR)
 	{
-	  base0 = get_inner_reference (TREE_OPERAND (arg0, 0),
-				       &bitsize, &bitpos0, &offset0, &mode,
-				       &unsignedp, &volatilep, false);
+	  base0
+	    = get_inner_reference (TREE_OPERAND (arg0, 0),
+				   &bitsize, &bitpos0, &offset0, &mode,
+				   &unsignedp, &reversep, &volatilep, false);
 	  if (TREE_CODE (base0) == INDIRECT_REF)
 	    base0 = TREE_OPERAND (base0, 0);
 	  else
@@ -8353,9 +8378,10 @@ fold_comparison (location_t loc, enum tr
       base1 = arg1;
       if (TREE_CODE (arg1) == ADDR_EXPR)
 	{
-	  base1 = get_inner_reference (TREE_OPERAND (arg1, 0),
-				       &bitsize, &bitpos1, &offset1, &mode,
-				       &unsignedp, &volatilep, false);
+	  base1
+	    = get_inner_reference (TREE_OPERAND (arg1, 0),
+				   &bitsize, &bitpos1, &offset1, &mode,
+				   &unsignedp, &reversep, &volatilep, false);
 	  if (TREE_CODE (base1) == INDIRECT_REF)
 	    base1 = TREE_OPERAND (base1, 0);
 	  else
@@ -14213,15 +14239,15 @@ split_address_to_core_and_offset (tree e
 {
   tree core;
   machine_mode mode;
-  int unsignedp, volatilep;
+  int unsignedp, reversep, volatilep;
   HOST_WIDE_INT bitsize;
   location_t loc = EXPR_LOCATION (exp);
 
   if (TREE_CODE (exp) == ADDR_EXPR)
     {
       core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
-				  poffset, &mode, &unsignedp, &volatilep,
-				  false);
+				  poffset, &mode, &unsignedp, &reversep,
+				  &volatilep, false);
       core = build_fold_addr_expr_loc (loc, core);
     }
   else
Index: expr.c
===================================================================
--- expr.c	(.../trunk/gcc)	(revision 228112)
+++ expr.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -134,11 +134,11 @@ static rtx_insn *compress_float_constant
 static rtx get_subtarget (rtx);
 static void store_constructor_field (rtx, unsigned HOST_WIDE_INT,
 				     HOST_WIDE_INT, machine_mode,
-				     tree, int, alias_set_type);
-static void store_constructor (tree, rtx, int, HOST_WIDE_INT);
+				     tree, int, alias_set_type, bool);
+static void store_constructor (tree, rtx, int, HOST_WIDE_INT, bool);
 static rtx store_field (rtx, HOST_WIDE_INT, HOST_WIDE_INT,
 			unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
-			machine_mode, tree, alias_set_type, bool);
+			machine_mode, tree, alias_set_type, bool, bool);
 
 static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (const_tree, const_tree);
 
@@ -1691,7 +1691,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, r
 		  && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode))
 		tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
 					     (bytepos % slen0) * BITS_PER_UNIT,
-					     1, NULL_RTX, mode, mode);
+					     1, NULL_RTX, mode, mode, false);
 	    }
 	  else
 	    {
@@ -1701,7 +1701,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, r
 	      mem = assign_stack_temp (GET_MODE (src), slen);
 	      emit_move_insn (mem, src);
 	      tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
-					   0, 1, NULL_RTX, mode, mode);
+					   0, 1, NULL_RTX, mode, mode, false);
 	    }
 	}
       /* FIXME: A SIMD parallel will eventually lead to a subreg of a
@@ -1744,7 +1744,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, r
       else
 	tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
 				     bytepos * BITS_PER_UNIT, 1, NULL_RTX,
-				     mode, mode);
+				     mode, mode, false);
 
       if (shift)
 	tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i],
@@ -2052,7 +2052,7 @@ emit_group_store (rtx orig_dst, rtx src,
 	  store_bit_field (dest,
 			   adj_bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
 			   bytepos * BITS_PER_UNIT, ssize * BITS_PER_UNIT - 1,
-			   VOIDmode, tmps[i]);
+			   VOIDmode, tmps[i], false);
 	}
 
       /* Optimize the access just a bit.  */
@@ -2065,7 +2065,7 @@ emit_group_store (rtx orig_dst, rtx src,
 
       else
 	store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
-			 0, 0, mode, tmps[i]);
+			 0, 0, mode, tmps[i], false);
     }
 
   /* Copy from the pseudo into the (probable) hard reg.  */
@@ -2195,7 +2195,9 @@ copy_blkmode_from_reg (rtx target, rtx s
       store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, 0, 0, copy_mode,
 		       extract_bit_field (src, bitsize,
 					  xbitpos % BITS_PER_WORD, 1,
-					  NULL_RTX, copy_mode, copy_mode));
+					  NULL_RTX, copy_mode, copy_mode,
+					  false),
+		       false);
     }
 }
 
@@ -2272,7 +2274,9 @@ copy_blkmode_to_reg (machine_mode mode,
 		       0, 0, word_mode,
 		       extract_bit_field (src_word, bitsize,
 					  bitpos % BITS_PER_WORD, 1,
-					  NULL_RTX, word_mode, word_mode));
+					  NULL_RTX, word_mode, word_mode,
+					  false),
+		       false);
     }
 
   if (mode == BLKmode)
@@ -3017,7 +3021,8 @@ write_complex_part (rtx cplx, rtx val, b
 	gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
     }
 
-  store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, 0, 0, imode, val);
+  store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, 0, 0, imode, val,
+		   false);
 }
 
 /* Extract one of the components of the complex value CPLX.  Extract the
@@ -3080,7 +3085,7 @@ read_complex_part (rtx cplx, bool imag_p
     }
 
   return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
-			    true, NULL_RTX, imode, imode);
+			    true, NULL_RTX, imode, imode, false);
 }
 \f
 /* A subroutine of emit_move_insn_1.  Yet another lowpart generator.
@@ -4470,7 +4475,7 @@ optimize_bitfield_assignment_op (unsigne
 				 unsigned HOST_WIDE_INT bitregion_start,
 				 unsigned HOST_WIDE_INT bitregion_end,
 				 machine_mode mode1, rtx str_rtx,
-				 tree to, tree src)
+				 tree to, tree src, bool reverse)
 {
   machine_mode str_mode = GET_MODE (str_rtx);
   unsigned int str_bitsize = GET_MODE_BITSIZE (str_mode);
@@ -4543,6 +4548,8 @@ optimize_bitfield_assignment_op (unsigne
     }
   else if (!REG_P (str_rtx) && GET_CODE (str_rtx) != SUBREG)
     return false;
+  else
+    gcc_assert (!reverse);
 
   /* If the bit field covers the whole REG/MEM, store_field
      will likely generate better code.  */
@@ -4553,7 +4560,7 @@ optimize_bitfield_assignment_op (unsigne
   if (bitpos + bitsize > str_bitsize)
     return false;
 
-  if (BYTES_BIG_ENDIAN)
+  if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
     bitpos = str_bitsize - bitpos - bitsize;
 
   switch (code)
@@ -4566,7 +4573,7 @@ optimize_bitfield_assignment_op (unsigne
 	 We might win by one instruction for the other bitfields
 	 too if insv/extv instructions aren't used, so that
 	 can be added later.  */
-      if (bitpos + bitsize != str_bitsize
+      if ((reverse || bitpos + bitsize != str_bitsize)
 	  && (bitsize != 1 || TREE_CODE (op1) != INTEGER_CST))
 	break;
 
@@ -4584,13 +4591,17 @@ optimize_bitfield_assignment_op (unsigne
 	  set_mem_expr (str_rtx, 0);
 	}
 
-      binop = code == PLUS_EXPR ? add_optab : sub_optab;
-      if (bitsize == 1 && bitpos + bitsize != str_bitsize)
+      if (bitsize == 1 && (reverse || bitpos + bitsize != str_bitsize))
 	{
 	  value = expand_and (str_mode, value, const1_rtx, NULL);
 	  binop = xor_optab;
 	}
+      else
+	binop = code == PLUS_EXPR ? add_optab : sub_optab;
+
       value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
+      if (reverse)
+	value = flip_storage_order (str_mode, value);
       result = expand_binop (str_mode, binop, str_rtx,
 			     value, str_rtx, 1, OPTAB_WIDEN);
       if (result != str_rtx)
@@ -4623,6 +4634,8 @@ optimize_bitfield_assignment_op (unsigne
 	  value = expand_and (str_mode, value, mask, NULL_RTX);
 	}
       value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
+      if (reverse)
+	value = flip_storage_order (str_mode, value);
       result = expand_binop (str_mode, binop, str_rtx,
 			     value, str_rtx, 1, OPTAB_WIDEN);
       if (result != str_rtx)
@@ -4677,10 +4690,10 @@ get_bit_range (unsigned HOST_WIDE_INT *b
       machine_mode rmode;
       HOST_WIDE_INT rbitsize, rbitpos;
       tree roffset;
-      int unsignedp;
-      int volatilep = 0;
+      int unsignedp, reversep, volatilep = 0;
       get_inner_reference (TREE_OPERAND (exp, 0), &rbitsize, &rbitpos,
-			   &roffset, &rmode, &unsignedp, &volatilep, false);
+			   &roffset, &rmode, &unsignedp, &reversep,
+			   &volatilep, false);
       if ((rbitpos % BITS_PER_UNIT) != 0)
 	{
 	  *bitstart = *bitend = 0;
@@ -4796,6 +4809,8 @@ expand_assignment (tree to, tree from, b
       reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
       reg = force_not_mem (reg);
       mem = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
+      if (TREE_CODE (to) == MEM_REF && REF_REVERSE_STORAGE_ORDER (to))
+	reg = flip_storage_order (mode, reg);
 
       if (icode != CODE_FOR_nothing)
 	{
@@ -4808,7 +4823,8 @@ expand_assignment (tree to, tree from, b
 	  expand_insn (icode, 2, ops);
 	}
       else
-	store_bit_field (mem, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, reg);
+	store_bit_field (mem, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, reg,
+			 false);
       return;
     }
 
@@ -4819,7 +4835,8 @@ expand_assignment (tree to, tree from, b
      problem.  Same for (partially) storing into a non-memory object.  */
   if (handled_component_p (to)
       || (TREE_CODE (to) == MEM_REF
-	  && mem_ref_refers_to_non_mem_p (to))
+	  && (REF_REVERSE_STORAGE_ORDER (to)
+	      || mem_ref_refers_to_non_mem_p (to)))
       || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE)
     {
       machine_mode mode1;
@@ -4827,13 +4844,12 @@ expand_assignment (tree to, tree from, b
       unsigned HOST_WIDE_INT bitregion_start = 0;
       unsigned HOST_WIDE_INT bitregion_end = 0;
       tree offset;
-      int unsignedp;
-      int volatilep = 0;
+      int unsignedp, reversep, volatilep = 0;
       tree tem;
 
       push_temp_slots ();
       tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
-				 &unsignedp, &volatilep, true);
+				 &unsignedp, &reversep, &volatilep, true);
 
       /* Make sure bitpos is not negative, it can wreak havoc later.  */
       if (bitpos < 0)
@@ -4952,22 +4968,22 @@ expand_assignment (tree to, tree from, b
 	  if (COMPLEX_MODE_P (TYPE_MODE (TREE_TYPE (from)))
 	      && bitpos == 0
 	      && bitsize == mode_bitsize)
-	    result = store_expr (from, to_rtx, false, nontemporal);
+	    result = store_expr (from, to_rtx, false, nontemporal, reversep);
 	  else if (bitsize == mode_bitsize / 2
 		   && (bitpos == 0 || bitpos == mode_bitsize / 2))
 	    result = store_expr (from, XEXP (to_rtx, bitpos != 0), false,
-				 nontemporal);
+				 nontemporal, reversep);
 	  else if (bitpos + bitsize <= mode_bitsize / 2)
 	    result = store_field (XEXP (to_rtx, 0), bitsize, bitpos,
 				  bitregion_start, bitregion_end,
-				  mode1, from,
-				  get_alias_set (to), nontemporal);
+				  mode1, from, get_alias_set (to),
+				  nontemporal, reversep);
 	  else if (bitpos >= mode_bitsize / 2)
 	    result = store_field (XEXP (to_rtx, 1), bitsize,
 				  bitpos - mode_bitsize / 2,
 				  bitregion_start, bitregion_end,
-				  mode1, from,
-				  get_alias_set (to), nontemporal);
+				  mode1, from, get_alias_set (to),
+				  nontemporal, reversep);
 	  else if (bitpos == 0 && bitsize == mode_bitsize)
 	    {
 	      rtx from_rtx;
@@ -4987,8 +5003,8 @@ expand_assignment (tree to, tree from, b
 	      write_complex_part (temp, XEXP (to_rtx, 1), true);
 	      result = store_field (temp, bitsize, bitpos,
 				    bitregion_start, bitregion_end,
-				    mode1, from,
-				    get_alias_set (to), nontemporal);
+				    mode1, from, get_alias_set (to),
+				    nontemporal, reversep);
 	      emit_move_insn (XEXP (to_rtx, 0), read_complex_part (temp, false));
 	      emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
 	    }
@@ -5007,14 +5023,14 @@ expand_assignment (tree to, tree from, b
 
 	  if (optimize_bitfield_assignment_op (bitsize, bitpos,
 					       bitregion_start, bitregion_end,
-					       mode1,
-					       to_rtx, to, from))
+					       mode1, to_rtx, to, from,
+					       reversep))
 	    result = NULL;
 	  else
 	    result = store_field (to_rtx, bitsize, bitpos,
 				  bitregion_start, bitregion_end,
-				  mode1, from,
-				  get_alias_set (to), nontemporal);
+				  mode1, from, get_alias_set (to),
+				  nontemporal, reversep);
 	}
 
       if (result)
@@ -5168,7 +5184,7 @@ expand_assignment (tree to, tree from, b
   /* Compute FROM and store the value in the rtx we got.  */
 
   push_temp_slots ();
-  result = store_expr_with_bounds (from, to_rtx, 0, nontemporal, to);
+  result = store_expr_with_bounds (from, to_rtx, 0, nontemporal, false, to);
   preserve_temp_slots (result);
   pop_temp_slots ();
   return;
@@ -5207,12 +5223,14 @@ emit_storent_insn (rtx to, rtx from)
 
    If NONTEMPORAL is true, try using a nontemporal store instruction.
 
+   If REVERSE is true, the store is to be done in reverse order.
+
    If BTARGET is not NULL then computed bounds of EXP are
    associated with BTARGET.  */
 
 rtx
 store_expr_with_bounds (tree exp, rtx target, int call_param_p,
-			bool nontemporal, tree btarget)
+			bool nontemporal, bool reverse, tree btarget)
 {
   rtx temp;
   rtx alt_rtl = NULL_RTX;
@@ -5234,7 +5252,8 @@ store_expr_with_bounds (tree exp, rtx ta
       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
 		   call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
       return store_expr_with_bounds (TREE_OPERAND (exp, 1), target,
-				     call_param_p, nontemporal, btarget);
+				     call_param_p, nontemporal, reverse,
+				     btarget);
     }
   else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
     {
@@ -5249,12 +5268,12 @@ store_expr_with_bounds (tree exp, rtx ta
       NO_DEFER_POP;
       jumpifnot (TREE_OPERAND (exp, 0), lab1, -1);
       store_expr_with_bounds (TREE_OPERAND (exp, 1), target, call_param_p,
-			      nontemporal, btarget);
+			      nontemporal, reverse, btarget);
       emit_jump_insn (targetm.gen_jump (lab2));
       emit_barrier ();
       emit_label (lab1);
       store_expr_with_bounds (TREE_OPERAND (exp, 2), target, call_param_p,
-			      nontemporal, btarget);
+			      nontemporal, reverse, btarget);
       emit_label (lab2);
       OK_DEFER_POP;
 
@@ -5393,9 +5412,9 @@ store_expr_with_bounds (tree exp, rtx ta
       rtx tmp_target;
 
   normal_expr:
-      /* If we want to use a nontemporal store, force the value to
-	 register first.  */
-      tmp_target = nontemporal ? NULL_RTX : target;
+      /* If we want to use a nontemporal or a reverse order store, force the
+	 value into a register first.  */
+      tmp_target = nontemporal || reverse ? NULL_RTX : target;
       temp = expand_expr_real (exp, tmp_target, GET_MODE (target),
 			       (call_param_p
 				? EXPAND_STACK_PARM : EXPAND_NORMAL),
@@ -5470,7 +5489,7 @@ store_expr_with_bounds (tree exp, rtx ta
 	      else
 		store_bit_field (target,
 				 INTVAL (expr_size (exp)) * BITS_PER_UNIT,
-				 0, 0, 0, GET_MODE (temp), temp);
+				 0, 0, 0, GET_MODE (temp), temp, reverse);
 	    }
 	  else
 	    convert_move (target, temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
@@ -5569,6 +5588,8 @@ store_expr_with_bounds (tree exp, rtx ta
 	;
       else
 	{
+	  if (reverse)
+	    temp = flip_storage_order (GET_MODE (target), temp);
 	  temp = force_operand (temp, target);
 	  if (temp != target)
 	    emit_move_insn (target, temp);
@@ -5580,9 +5601,11 @@ store_expr_with_bounds (tree exp, rtx ta
 
 /* Same as store_expr_with_bounds but ignoring bounds of EXP.  */
 rtx
-store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
+store_expr (tree exp, rtx target, int call_param_p, bool nontemporal,
+	    bool reverse)
 {
-  return store_expr_with_bounds (exp, target, call_param_p, nontemporal, NULL);
+  return store_expr_with_bounds (exp, target, call_param_p, nontemporal,
+				 reverse, NULL);
 }
 \f
 /* Return true if field F of structure TYPE is a flexible array.  */
@@ -5802,8 +5825,12 @@ categorize_ctor_elements_1 (const_tree c
 	    init_elts += mult * tc;
 
 	    if (const_from_elts_p && const_p)
-	      const_p = initializer_constant_valid_p (value, elt_type)
-			!= NULL_TREE;
+	      const_p
+		= initializer_constant_valid_p (value,
+						elt_type,
+						TYPE_REVERSE_STORAGE_ORDER
+						(TREE_TYPE (ctor)))
+		  != NULL_TREE;
 	  }
 	  break;
 	}
@@ -5908,6 +5935,7 @@ all_zeros_p (const_tree exp)
    TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
    CLEARED is as for store_constructor.
    ALIAS_SET is the alias set to use for any stores.
+   If REVERSE is true, the store is to be done in reverse order.
 
    This provides a recursive shortcut back to store_constructor when it isn't
    necessary to go through store_field.  This is so that we can pass through
@@ -5917,7 +5945,8 @@ all_zeros_p (const_tree exp)
 static void
 store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
 			 HOST_WIDE_INT bitpos, machine_mode mode,
-			 tree exp, int cleared, alias_set_type alias_set)
+			 tree exp, int cleared,
+			 alias_set_type alias_set, bool reverse)
 {
   if (TREE_CODE (exp) == CONSTRUCTOR
       /* We can only call store_constructor recursively if the size and
@@ -5946,10 +5975,12 @@ store_constructor_field (rtx target, uns
 	  set_mem_alias_set (target, alias_set);
 	}
 
-      store_constructor (exp, target, cleared, bitsize / BITS_PER_UNIT);
+      store_constructor (exp, target, cleared, bitsize / BITS_PER_UNIT,
+			 reverse);
     }
   else
-    store_field (target, bitsize, bitpos, 0, 0, mode, exp, alias_set, false);
+    store_field (target, bitsize, bitpos, 0, 0, mode, exp, alias_set, false,
+		 reverse);
 }
 
 
@@ -5975,10 +6006,12 @@ fields_length (const_tree type)
    CLEARED is true if TARGET is known to have been zero'd.
    SIZE is the number of bytes of TARGET we are allowed to modify: this
    may not be the same as the size of EXP if we are assigning to a field
-   which has been packed to exclude padding bits.  */
+   which has been packed to exclude padding bits.
+   If REVERSE is true, the store is to be done in reverse order.  */
 
 static void
-store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
+store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size,
+		   bool reverse)
 {
   tree type = TREE_TYPE (exp);
   HOST_WIDE_INT exp_size = int_size_in_bytes (type);
@@ -5992,6 +6025,9 @@ store_constructor (tree exp, rtx target,
 	unsigned HOST_WIDE_INT idx;
 	tree field, value;
 
+	/* The storage order is specified for every aggregate type.  */
+	reverse = TYPE_REVERSE_STORAGE_ORDER (type);
+
 	/* If size is zero or the target is already cleared, do nothing.  */
 	if (size == 0 || cleared)
 	  cleared = 1;
@@ -6135,7 +6171,8 @@ store_constructor (tree exp, rtx target,
 
 	    store_constructor_field (to_rtx, bitsize, bitpos, mode,
 				     value, cleared,
-				     get_alias_set (TREE_TYPE (field)));
+				     get_alias_set (TREE_TYPE (field)),
+				     reverse);
 	  }
 	break;
       }
@@ -6150,6 +6187,9 @@ store_constructor (tree exp, rtx target,
 	HOST_WIDE_INT minelt = 0;
 	HOST_WIDE_INT maxelt = 0;
 
+	/* The storage order is specified for every aggregate type.  */
+	reverse = TYPE_REVERSE_STORAGE_ORDER (type);
+
 	domain = TYPE_DOMAIN (type);
 	const_bounds_p = (TYPE_MIN_VALUE (domain)
 			  && TYPE_MAX_VALUE (domain)
@@ -6290,7 +6330,7 @@ store_constructor (tree exp, rtx target,
 
 			store_constructor_field
 			  (target, bitsize, bitpos, mode, value, cleared,
-			   get_alias_set (elttype));
+			   get_alias_set (elttype), reverse);
 		      }
 		  }
 		else
@@ -6305,7 +6345,7 @@ store_constructor (tree exp, rtx target,
 					VAR_DECL, NULL_TREE, domain);
 		    index_r = gen_reg_rtx (promote_decl_mode (index, NULL));
 		    SET_DECL_RTL (index, index_r);
-		    store_expr (lo_index, index_r, 0, false);
+		    store_expr (lo_index, index_r, 0, false, reverse);
 
 		    /* Build the head of the loop.  */
 		    do_pending_stack_adjust ();
@@ -6330,9 +6370,9 @@ store_constructor (tree exp, rtx target,
 		    xtarget = adjust_address (xtarget, mode, 0);
 		    if (TREE_CODE (value) == CONSTRUCTOR)
 		      store_constructor (value, xtarget, cleared,
-					 bitsize / BITS_PER_UNIT);
+					 bitsize / BITS_PER_UNIT, reverse);
 		    else
-		      store_expr (value, xtarget, 0, false);
+		      store_expr (value, xtarget, 0, false, reverse);
 
 		    /* Generate a conditional jump to exit the loop.  */
 		    exit_cond = build2 (LT_EXPR, integer_type_node,
@@ -6375,7 +6415,7 @@ store_constructor (tree exp, rtx target,
 					  expand_normal (position),
 					  highest_pow2_factor (position));
 		xtarget = adjust_address (xtarget, mode, 0);
-		store_expr (value, xtarget, 0, false);
+		store_expr (value, xtarget, 0, false, reverse);
 	      }
 	    else
 	      {
@@ -6393,7 +6433,8 @@ store_constructor (tree exp, rtx target,
 		    MEM_KEEP_ALIAS_SET_P (target) = 1;
 		  }
 		store_constructor_field (target, bitsize, bitpos, mode, value,
-					 cleared, get_alias_set (elttype));
+					 cleared, get_alias_set (elttype),
+					 reverse);
 	      }
 	  }
 	break;
@@ -6526,7 +6567,7 @@ store_constructor (tree exp, rtx target,
 		  : eltmode;
 		bitpos = eltpos * elt_size;
 		store_constructor_field (target, bitsize, bitpos, value_mode,
-					 value, cleared, alias);
+					 value, cleared, alias, reverse);
 	      }
 	  }
 
@@ -6559,14 +6600,16 @@ store_constructor (tree exp, rtx target,
    (in general) be different from that for TARGET, since TARGET is a
    reference to the containing structure.
 
-   If NONTEMPORAL is true, try generating a nontemporal store.  */
+   If NONTEMPORAL is true, try generating a nontemporal store.
+
+   If REVERSE is true, the store is to be done in reverse order.  */
 
 static rtx
 store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
 	     unsigned HOST_WIDE_INT bitregion_start,
 	     unsigned HOST_WIDE_INT bitregion_end,
 	     machine_mode mode, tree exp,
-	     alias_set_type alias_set, bool nontemporal)
+	     alias_set_type alias_set, bool nontemporal,  bool reverse)
 {
   if (TREE_CODE (exp) == ERROR_MARK)
     return const0_rtx;
@@ -6581,7 +6624,7 @@ store_field (rtx target, HOST_WIDE_INT b
       /* We're storing into a struct containing a single __complex.  */
 
       gcc_assert (!bitpos);
-      return store_expr (exp, target, 0, nontemporal);
+      return store_expr (exp, target, 0, nontemporal, reverse);
     }
 
   /* If the structure is in a register or if the component
@@ -6643,16 +6686,27 @@ store_field (rtx target, HOST_WIDE_INT b
 
       temp = expand_normal (exp);
 
-      /* If BITSIZE is narrower than the size of the type of EXP
-	 we will be narrowing TEMP.  Normally, what's wanted are the
-	 low-order bits.  However, if EXP's type is a record and this is
-	 big-endian machine, we want the upper BITSIZE bits.  */
-      if (BYTES_BIG_ENDIAN && GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
-	  && bitsize < (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (temp))
-	  && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
-	temp = expand_shift (RSHIFT_EXPR, GET_MODE (temp), temp,
-			     GET_MODE_BITSIZE (GET_MODE (temp)) - bitsize,
-			     NULL_RTX, 1);
+      /* If the value has a record type and an integral mode then, if BITSIZE
+	 is narrower than this mode and this is a big-endian machine, we must
+	 first put the value into the low-order bits.  Moreover, the field may
+	 be not aligned on a byte boundary; in this case, if it has reverse
+	 storage order, it needs to be accessed as a scalar field with reverse
+	 storage order and we must first put the value into target order.  */
+      if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
+	  && GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT)
+	{
+	  HOST_WIDE_INT size = GET_MODE_BITSIZE (GET_MODE (temp));
+
+	  reverse = TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (exp));
+
+	  if (reverse)
+	    temp = flip_storage_order (GET_MODE (temp), temp);
+
+	  if (bitsize < size
+	      && reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
+	    temp = expand_shift (RSHIFT_EXPR, GET_MODE (temp), temp,
+				 size - bitsize, NULL_RTX, 1);
+	}
 
       /* Unless MODE is VOIDmode or BLKmode, convert TEMP to MODE.  */
       if (mode != VOIDmode && mode != BLKmode
@@ -6712,7 +6766,7 @@ store_field (rtx target, HOST_WIDE_INT b
 	      temp_target = gen_reg_rtx (mode);
 	      temp_target
 	        = extract_bit_field (temp, size * BITS_PER_UNIT, 0, 1,
-				     temp_target, mode, mode);
+				     temp_target, mode, mode, false);
 	      temp = temp_target;
 	    }
 	}
@@ -6720,7 +6774,7 @@ store_field (rtx target, HOST_WIDE_INT b
       /* Store the value in the bitfield.  */
       store_bit_field (target, bitsize, bitpos,
 		       bitregion_start, bitregion_end,
-		       mode, temp);
+		       mode, temp, reverse);
 
       return const0_rtx;
     }
@@ -6735,7 +6789,7 @@ store_field (rtx target, HOST_WIDE_INT b
       if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
 	set_mem_alias_set (to_rtx, alias_set);
 
-      return store_expr (exp, to_rtx, 0, nontemporal);
+      return store_expr (exp, to_rtx, 0, nontemporal, reverse);
     }
 }
 \f
@@ -6744,7 +6798,8 @@ store_field (rtx target, HOST_WIDE_INT b
    codes and find the ultimate containing object, which we return.
 
    We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
-   bit position, and *PUNSIGNEDP to the signedness of the field.
+   bit position, *PUNSIGNEDP to the signedness and *PREVERSEP to the
+   storage order of the field.
    If the position of the field is variable, we store a tree
    giving the variable offset (in units) in *POFFSET.
    This offset is in addition to the bit position.
@@ -6778,7 +6833,7 @@ tree
 get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
 		     HOST_WIDE_INT *pbitpos, tree *poffset,
 		     machine_mode *pmode, int *punsignedp,
-		     int *pvolatilep, bool keep_aligning)
+		     int *preversep, int *pvolatilep, bool keep_aligning)
 {
   tree size_tree = 0;
   machine_mode mode = VOIDmode;
@@ -6786,8 +6841,8 @@ get_inner_reference (tree exp, HOST_WIDE
   tree offset = size_zero_node;
   offset_int bit_offset = 0;
 
-  /* First get the mode, signedness, and size.  We do this from just the
-     outermost expression.  */
+  /* First get the mode, signedness, storage order and size.  We do this from
+     just the outermost expression.  */
   *pbitsize = -1;
   if (TREE_CODE (exp) == COMPONENT_REF)
     {
@@ -6840,6 +6895,8 @@ get_inner_reference (tree exp, HOST_WIDE
 	*pbitsize = tree_to_uhwi (size_tree);
     }
 
+  *preversep = reverse_storage_order_for_component_p (exp);
+
   /* Compute cumulative bit-offset for nested component-refs and array-refs,
      and find the ultimate containing object.  */
   while (1)
@@ -7516,7 +7573,7 @@ expand_expr_addr_expr_1 (tree exp, rtx t
   rtx result, subtarget;
   tree inner, offset;
   HOST_WIDE_INT bitsize, bitpos;
-  int volatilep, unsignedp;
+  int unsignedp, reversep, volatilep = 0;
   machine_mode mode1;
 
   /* If we are taking the address of a constant and are at the top level,
@@ -7623,8 +7680,8 @@ expand_expr_addr_expr_1 (tree exp, rtx t
 	 handle "aligning nodes" here: we can just bypass them because
 	 they won't change the final object whose address will be returned
 	 (they actually exist only for that purpose).  */
-      inner = get_inner_reference (exp, &bitsize, &bitpos, &offset,
-				   &mode1, &unsignedp, &volatilep, false);
+      inner = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
+				   &unsignedp, &reversep, &volatilep, false);
       break;
     }
 
@@ -7808,7 +7865,7 @@ expand_constructor (tree exp, rtx target
       target = assign_temp (type, TREE_ADDRESSABLE (exp), 1);
     }
 
-  store_constructor (exp, target, 0, int_expr_size (exp));
+  store_constructor (exp, target, 0, int_expr_size (exp), false);
   return target;
 }
 
@@ -8081,11 +8138,12 @@ expand_expr_real_2 (sepops ops, rtx targ
 	    store_expr (treeop0,
 			adjust_address (target, TYPE_MODE (valtype), 0),
 			modifier == EXPAND_STACK_PARM,
-			false);
+			false, TYPE_REVERSE_STORAGE_ORDER (type));
 
 	  else
 	    {
-	      gcc_assert (REG_P (target));
+	      gcc_assert (REG_P (target)
+			  && !TYPE_REVERSE_STORAGE_ORDER (type));
 
 	      /* Store this field into a union of the proper type.  */
 	      store_field (target,
@@ -8093,7 +8151,8 @@ expand_expr_real_2 (sepops ops, rtx targ
 						    (treeop0))
 				 * BITS_PER_UNIT),
 				(HOST_WIDE_INT) GET_MODE_BITSIZE (mode)),
-			   0, 0, 0, TYPE_MODE (valtype), treeop0, 0, false);
+			   0, 0, 0, TYPE_MODE (valtype), treeop0, 0,
+			   false, false);
 	    }
 
 	  /* Return the entire union.  */
@@ -9122,7 +9181,7 @@ expand_expr_real_2 (sepops ops, rtx targ
         int index = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (vec_mode) - 1 : 0;
 	int bitsize = GET_MODE_UNIT_BITSIZE (vec_mode);
         temp = extract_bit_field (temp, bitsize, bitsize * index, unsignedp,
-				  target, mode, mode);
+				  target, mode, mode, false);
         gcc_assert (temp);
         return temp;
       }
@@ -9278,14 +9337,14 @@ expand_expr_real_2 (sepops ops, rtx targ
 	jumpifnot (treeop0, lab0, -1);
 	store_expr (treeop1, temp,
 		    modifier == EXPAND_STACK_PARM,
-		    false);
+		    false, false);
 
 	emit_jump_insn (targetm.gen_jump (lab1));
 	emit_barrier ();
 	emit_label (lab0);
 	store_expr (treeop2, temp,
 		    modifier == EXPAND_STACK_PARM,
-		    false);
+		    false, false);
 
 	emit_label (lab1);
 	OK_DEFER_POP;
@@ -9838,6 +9897,7 @@ expand_expr_real_1 (tree exp, rtx target
 
     case MEM_REF:
       {
+	const bool reverse = REF_REVERSE_STORAGE_ORDER (exp);
 	addr_space_t as
 	  = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
 	machine_mode address_mode;
@@ -9852,6 +9912,7 @@ expand_expr_real_1 (tree exp, rtx target
 	    HOST_WIDE_INT offset = mem_ref_offset (exp).to_short_addr ();
 	    base = TREE_OPERAND (base, 0);
 	    if (offset == 0
+	        && !reverse
 		&& tree_fits_uhwi_p (TYPE_SIZE (type))
 		&& (GET_MODE_BITSIZE (DECL_MODE (base))
 		    == tree_to_uhwi (TYPE_SIZE (type))))
@@ -9861,13 +9922,14 @@ expand_expr_real_1 (tree exp, rtx target
 	      {
 		temp = assign_stack_temp (DECL_MODE (base),
 					  GET_MODE_SIZE (DECL_MODE (base)));
-		store_expr (base, temp, 0, false);
+		store_expr (base, temp, 0, false, false);
 		temp = adjust_address (temp, BLKmode, offset);
 		set_mem_size (temp, int_size_in_bytes (type));
 		return temp;
 	      }
 	    exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
 			  bitsize_int (offset * BITS_PER_UNIT));
+	    REF_REVERSE_STORAGE_ORDER (exp) = reverse;
 	    return expand_expr (exp, target, tmode, modifier);
 	  }
 	address_mode = targetm.addr_space.address_mode (as);
@@ -9917,8 +9979,12 @@ expand_expr_real_1 (tree exp, rtx target
 					0, TYPE_UNSIGNED (TREE_TYPE (exp)),
 					(modifier == EXPAND_STACK_PARM
 					 ? NULL_RTX : target),
-					mode, mode);
+					mode, mode, false);
 	  }
+	if (reverse
+	    && modifier != EXPAND_MEMORY
+	    && modifier != EXPAND_WRITE)
+	  temp = flip_storage_order (mode, temp);
 	return temp;
       }
 
@@ -10124,9 +10190,10 @@ expand_expr_real_1 (tree exp, rtx target
 	machine_mode mode1, mode2;
 	HOST_WIDE_INT bitsize, bitpos;
 	tree offset;
-	int volatilep = 0, must_force_mem;
-	tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
-					&mode1, &unsignedp, &volatilep, true);
+	int reversep, volatilep = 0, must_force_mem;
+	tree tem
+	  = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
+				 &unsignedp, &reversep, &volatilep, true);
 	rtx orig_op0, memloc;
 	bool clear_mem_expr = false;
 
@@ -10181,7 +10248,11 @@ expand_expr_real_1 (tree exp, rtx target
 	  {
 	    if (bitpos == 0
 		&& bitsize == GET_MODE_BITSIZE (GET_MODE (op0)))
-	      return op0;
+	      {
+		if (reversep)
+		  op0 = flip_storage_order (GET_MODE (op0), op0);
+		return op0;
+	      }
 	    if (bitpos == 0
 		&& bitsize == GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
 		&& bitsize)
@@ -10367,20 +10438,38 @@ expand_expr_real_1 (tree exp, rtx target
 	    if (MEM_P (op0) && REG_P (XEXP (op0, 0)))
 	      mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
 
+	    /* If the result has a record type and the extraction is done in
+	       an integral mode, then the field may be not aligned on a byte
+	       boundary; in this case, if it has reverse storage order, it
+	       needs to be extracted as a scalar field with reverse storage
+	       order and put back into memory order afterwards.  */
+	    if (TREE_CODE (type) == RECORD_TYPE
+		&& GET_MODE_CLASS (ext_mode) == MODE_INT)
+	      reversep = TYPE_REVERSE_STORAGE_ORDER (type);
+
 	    op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
 				     (modifier == EXPAND_STACK_PARM
 				      ? NULL_RTX : target),
-				     ext_mode, ext_mode);
+				     ext_mode, ext_mode, reversep);
+
+	    /* If the result has a record type and the mode of OP0 is an
+	       integral mode then, if BITSIZE is narrower than this mode
+	       and this is a big-endian machine, we must put the field
+	       into the high-order bits.  And we must also put it back
+	       into memory order if it has been previously reversed.  */
+	    if (TREE_CODE (type) == RECORD_TYPE
+		&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
+	      {
+		HOST_WIDE_INT size = GET_MODE_BITSIZE (GET_MODE (op0));
 
-	    /* If the result is a record type and BITSIZE is narrower than
-	       the mode of OP0, an integral mode, and this is a big endian
-	       machine, we must put the field into the high-order bits.  */
-	    if (TREE_CODE (type) == RECORD_TYPE && BYTES_BIG_ENDIAN
-		&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
-		&& bitsize < (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (op0)))
-	      op0 = expand_shift (LSHIFT_EXPR, GET_MODE (op0), op0,
-				  GET_MODE_BITSIZE (GET_MODE (op0))
-				  - bitsize, op0, 1);
+		if (bitsize < size
+		    && reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
+		  op0 = expand_shift (LSHIFT_EXPR, GET_MODE (op0), op0,
+				      size - bitsize, op0, 1);
+
+		if (reversep)
+		  op0 = flip_storage_order (GET_MODE (op0), op0);
+	      }
 
 	    /* If the result type is BLKmode, store the data into a temporary
 	       of the appropriate type, but with the mode corresponding to the
@@ -10426,6 +10515,12 @@ expand_expr_real_1 (tree exp, rtx target
 	  set_mem_expr (op0, NULL_TREE);
 
 	MEM_VOLATILE_P (op0) |= volatilep;
+
+        if (reversep
+	    && modifier != EXPAND_MEMORY
+	    && modifier != EXPAND_WRITE)
+	  op0 = flip_storage_order (mode1, op0);
+
 	if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
 	    || modifier == EXPAND_CONST_ADDRESS
 	    || modifier == EXPAND_INITIALIZER)
@@ -10489,17 +10584,16 @@ expand_expr_real_1 (tree exp, rtx target
 	machine_mode mode1;
 	HOST_WIDE_INT bitsize, bitpos;
 	tree offset;
-	int unsignedp;
-	int volatilep = 0;
+	int unsignedp, reversep, volatilep = 0;
 	tree tem
-	  = get_inner_reference (treeop0, &bitsize, &bitpos,
-				 &offset, &mode1, &unsignedp, &volatilep,
-				 true);
+	  = get_inner_reference (treeop0, &bitsize, &bitpos, &offset, &mode1,
+				 &unsignedp, &reversep, &volatilep, true);
 	rtx orig_op0;
 
 	/* ??? We should work harder and deal with non-zero offsets.  */
 	if (!offset
 	    && (bitpos % BITS_PER_UNIT) == 0
+	    && !reversep
 	    && bitsize >= 0
 	    && compare_tree_int (TYPE_SIZE (type), bitsize) == 0)
 	  {
@@ -10573,7 +10667,7 @@ expand_expr_real_1 (tree exp, rtx target
       else if (reduce_bit_field)
 	return extract_bit_field (op0, TYPE_PRECISION (type), 0,
 				  TYPE_UNSIGNED (type), NULL_RTX,
-				  mode, mode);
+				  mode, mode, false);
       /* As a last resort, spill op0 to memory, and reload it in a
 	 different mode.  */
       else if (!MEM_P (op0))
Index: expr.h
===================================================================
--- expr.h	(.../trunk/gcc)	(revision 228112)
+++ expr.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -212,6 +212,7 @@ extern rtx_insn *emit_move_complex_push
 extern rtx_insn *emit_move_complex_parts (rtx, rtx);
 extern rtx read_complex_part (rtx, bool);
 extern void write_complex_part (rtx, rtx, bool);
+extern rtx read_complex_part (rtx, bool);
 extern rtx emit_move_resolve_push (machine_mode, rtx);
 
 /* Push a block of length SIZE (perhaps variable)
@@ -229,8 +230,8 @@ extern void expand_assignment (tree, tre
    and storing the value into TARGET.
    If SUGGEST_REG is nonzero, copy the value through a register
    and return that register, if that is possible.  */
-extern rtx store_expr_with_bounds (tree, rtx, int, bool, tree);
-extern rtx store_expr (tree, rtx, int, bool);
+extern rtx store_expr_with_bounds (tree, rtx, int, bool, bool, tree);
+extern rtx store_expr (tree, rtx, int, bool, bool);
 
 /* Given an rtx that may include add and multiply operations,
    generate them as insns and return a pseudo-reg containing the value.
Index: stor-layout.c
===================================================================
--- stor-layout.c	(.../trunk/gcc)	(revision 228112)
+++ stor-layout.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -2046,11 +2046,16 @@ finish_record_layout (record_layout_info
   /* Compute bitfield representatives.  */
   finish_bitfield_layout (rli->t);
 
-  /* Propagate TYPE_PACKED to variants.  With C++ templates,
-     handle_packed_attribute is too early to do this.  */
+  /* Propagate TYPE_PACKED and TYPE_REVERSE_STORAGE_ORDER to variants.
+     With C++ templates, it is too early to do this when the attribute
+     is being parsed.  */
   for (variant = TYPE_NEXT_VARIANT (rli->t); variant;
        variant = TYPE_NEXT_VARIANT (variant))
-    TYPE_PACKED (variant) = TYPE_PACKED (rli->t);
+    {
+      TYPE_PACKED (variant) = TYPE_PACKED (rli->t);
+      TYPE_REVERSE_STORAGE_ORDER (variant)
+	= TYPE_REVERSE_STORAGE_ORDER (rli->t);
+    }
 
   /* Lay out any static members.  This is done now because their type
      may use the record's type.  */
Index: gimplify.c
===================================================================
--- gimplify.c	(.../trunk/gcc)	(revision 228112)
+++ gimplify.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -8256,6 +8256,8 @@ gimplify_expr (tree *expr_p, gimple_seq
 			     TREE_OPERAND (*expr_p, 1));
 	  if (tmp)
 	    {
+	      REF_REVERSE_STORAGE_ORDER (tmp)
+	        = REF_REVERSE_STORAGE_ORDER (*expr_p);
 	      *expr_p = tmp;
 	      recalculate_side_effects (*expr_p);
 	      ret = GS_OK;
Index: calls.c
===================================================================
--- calls.c	(.../trunk/gcc)	(revision 228112)
+++ calls.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1086,7 +1086,7 @@ store_unaligned_arguments_into_pseudos (
 
 	    args[i].aligned_regs[j] = reg;
 	    word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
-				      word_mode, word_mode);
+				      word_mode, word_mode, false);
 
 	    /* There is no need to restrict this code to loading items
 	       in TYPE_ALIGN sized hunks.  The bitfield instructions can
@@ -1103,7 +1103,7 @@ store_unaligned_arguments_into_pseudos (
 
 	    bytes -= bitsize / BITS_PER_UNIT;
 	    store_bit_field (reg, bitsize, endian_correction, 0, 0,
-			     word_mode, word);
+			     word_mode, word, false);
 	  }
       }
 }
@@ -1384,7 +1384,7 @@ initialize_argument_information (int num
 	      else
 		copy = assign_temp (type, 1, 0);
 
-	      store_expr (args[i].tree_value, copy, 0, false);
+	      store_expr (args[i].tree_value, copy, 0, false, false);
 
 	      /* Just change the const function to pure and then let
 		 the next test clear the pure based on
@@ -2105,8 +2105,8 @@ load_register_parameters (struct arg_dat
 		  rtx dest = gen_rtx_REG (word_mode, REGNO (reg) + nregs - 1);
 		  unsigned int bitoff = (nregs - 1) * BITS_PER_WORD;
 		  unsigned int bitsize = size * BITS_PER_UNIT - bitoff;
-		  rtx x = extract_bit_field (mem, bitsize, bitoff, 1,
-					     dest, word_mode, word_mode);
+		  rtx x = extract_bit_field (mem, bitsize, bitoff, 1, dest,
+					     word_mode, word_mode, false);
 		  if (BYTES_BIG_ENDIAN)
 		    x = expand_shift (LSHIFT_EXPR, word_mode, x,
 				      BITS_PER_WORD - bitsize, dest, 1);
Index: expmed.c
===================================================================
--- expmed.c	(.../trunk/gcc)	(revision 228112)
+++ expmed.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -57,24 +57,24 @@ static void store_fixed_bit_field (rtx,
 				   unsigned HOST_WIDE_INT,
 				   unsigned HOST_WIDE_INT,
 				   unsigned HOST_WIDE_INT,
-				   rtx);
+				   rtx, bool);
 static void store_fixed_bit_field_1 (rtx, unsigned HOST_WIDE_INT,
 				     unsigned HOST_WIDE_INT,
-				     rtx);
+				     rtx, bool);
 static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT,
 				   unsigned HOST_WIDE_INT,
 				   unsigned HOST_WIDE_INT,
 				   unsigned HOST_WIDE_INT,
-				   rtx);
+				   rtx, bool);
 static rtx extract_fixed_bit_field (machine_mode, rtx,
 				    unsigned HOST_WIDE_INT,
-				    unsigned HOST_WIDE_INT, rtx, int);
+				    unsigned HOST_WIDE_INT, rtx, int, bool);
 static rtx extract_fixed_bit_field_1 (machine_mode, rtx,
 				      unsigned HOST_WIDE_INT,
-				      unsigned HOST_WIDE_INT, rtx, int);
+				      unsigned HOST_WIDE_INT, rtx, int, bool);
 static rtx lshift_value (machine_mode, unsigned HOST_WIDE_INT, int);
 static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT,
-				    unsigned HOST_WIDE_INT, int);
+				    unsigned HOST_WIDE_INT, int, bool);
 static void do_cmp_and_jump (rtx, rtx, enum rtx_code, machine_mode, rtx_code_label *);
 static rtx expand_smod_pow2 (machine_mode, rtx, HOST_WIDE_INT);
 static rtx expand_sdiv_pow2 (machine_mode, rtx, HOST_WIDE_INT);
@@ -332,6 +332,94 @@ negate_rtx (machine_mode mode, rtx x)
   return result;
 }
 
+/* Whether reverse storage order is supported on the target.  */
+static int reverse_storage_order_supported = -1;
+
+/* Check whether reverse storage order is supported on the target.  */
+
+static void
+check_reverse_storage_order_support (void)
+{
+  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+    {
+      reverse_storage_order_supported = 0;
+      sorry ("reverse scalar storage order");
+    }
+  else
+    reverse_storage_order_supported = 1;
+}
+
+/* Whether reverse FP storage order is supported on the target.  */
+static int reverse_float_storage_order_supported = -1;
+
+/* Check whether reverse FP storage order is supported on the target.  */
+
+static void
+check_reverse_float_storage_order_support (void)
+{
+  if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+    {
+      reverse_float_storage_order_supported = 0;
+      sorry ("reverse floating-point scalar storage order");
+    }
+  else
+    reverse_float_storage_order_supported = 1;
+}
+
+/* Return an rtx representing value of X with reverse storage order.
+   MODE is the intended mode of the result,
+   useful if X is a CONST_INT.  */
+
+rtx
+flip_storage_order (enum machine_mode mode, rtx x)
+{
+  enum machine_mode int_mode;
+  rtx result;
+
+  if (mode == QImode)
+    return x;
+
+  if (COMPLEX_MODE_P (mode))
+    {
+      rtx real = read_complex_part (x, false);
+      rtx imag = read_complex_part (x, true);
+
+      real = flip_storage_order (GET_MODE_INNER (mode), real);
+      imag = flip_storage_order (GET_MODE_INNER (mode), imag);
+
+      return gen_rtx_CONCAT (mode, real, imag);
+    }
+
+  if (__builtin_expect (reverse_storage_order_supported < 0, 0))
+    check_reverse_storage_order_support ();
+
+  if (SCALAR_INT_MODE_P (mode))
+    int_mode = mode;
+  else
+    {
+      if (FLOAT_MODE_P (mode)
+	  && __builtin_expect (reverse_float_storage_order_supported < 0, 0))
+	check_reverse_float_storage_order_support ();
+
+      int_mode = mode_for_size (GET_MODE_PRECISION (mode), MODE_INT, 0);
+      if (int_mode == BLKmode)
+	{
+	  sorry ("reverse storage order for %smode", GET_MODE_NAME (mode));
+	  return x;
+	}
+      x = gen_lowpart (int_mode, x);
+    }
+
+  result = simplify_unary_operation (BSWAP, int_mode, x, int_mode);
+  if (result == 0)
+    result = expand_unop (int_mode, bswap_optab, x, NULL_RTX, 1);
+
+  if (int_mode != mode)
+    result = gen_lowpart (mode, result);
+
+  return result;
+}
+
 /* Adjust bitfield memory MEM so that it points to the first unit of mode
    MODE that contains a bitfield of size BITSIZE at bit position BITNUM.
    If MODE is BLKmode, return a reference to every byte in the bitfield.
@@ -635,7 +723,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
 		   unsigned HOST_WIDE_INT bitregion_start,
 		   unsigned HOST_WIDE_INT bitregion_end,
 		   machine_mode fieldmode,
-		   rtx value, bool fallback_p)
+		   rtx value, bool reverse, bool fallback_p)
 {
   rtx op0 = str_rtx;
   rtx orig_value;
@@ -713,6 +801,8 @@ store_bit_field_1 (rtx str_rtx, unsigned
 	  sub = simplify_gen_subreg (GET_MODE (op0), value, fieldmode, 0);
 	  if (sub)
 	    {
+	      if (reverse)
+		sub = flip_storage_order (GET_MODE (op0), sub);
 	      emit_move_insn (op0, sub);
 	      return true;
 	    }
@@ -723,6 +813,8 @@ store_bit_field_1 (rtx str_rtx, unsigned
 				     bitnum / BITS_PER_UNIT);
 	  if (sub)
 	    {
+	      if (reverse)
+		value = flip_storage_order (fieldmode, value);
 	      emit_move_insn (sub, value);
 	      return true;
 	    }
@@ -735,6 +827,8 @@ store_bit_field_1 (rtx str_rtx, unsigned
   if (simple_mem_bitfield_p (op0, bitsize, bitnum, fieldmode))
     {
       op0 = adjust_bitfield_address (op0, fieldmode, bitnum / BITS_PER_UNIT);
+      if (reverse)
+	value = flip_storage_order (fieldmode, value);
       emit_move_insn (op0, value);
       return true;
     }
@@ -761,6 +855,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
      can be done with a movstrict instruction.  */
 
   if (!MEM_P (op0)
+      && !reverse
       && lowpart_bit_field_p (bitnum, bitsize, GET_MODE (op0))
       && bitsize == GET_MODE_BITSIZE (fieldmode)
       && optab_handler (movstrict_optab, fieldmode) != CODE_FOR_nothing)
@@ -804,7 +899,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
 	 be less than full.
 	 However, only do that if the value is not BLKmode.  */
 
-      unsigned int backwards = WORDS_BIG_ENDIAN && fieldmode != BLKmode;
+      const bool backwards = WORDS_BIG_ENDIAN && fieldmode != BLKmode;
       unsigned int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
       unsigned int i;
       rtx_insn *last;
@@ -827,7 +922,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
 				  ? GET_MODE_SIZE (fieldmode) / UNITS_PER_WORD
 				  - i - 1
 				  : i);
-	  unsigned int bit_offset = (backwards
+	  unsigned int bit_offset = (backwards ^ reverse
 				     ? MAX ((int) bitsize - ((int) i + 1)
 					    * BITS_PER_WORD,
 					    0)
@@ -851,7 +946,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
 				  bitnum + bit_offset,
 				  bitregion_start, bitregion_end,
 				  word_mode,
-				  value_word, fallback_p))
+				  value_word, reverse, fallback_p))
 	    {
 	      delete_insns_since (last);
 	      return false;
@@ -887,7 +982,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
 	    return false;
 
 	  store_split_bit_field (op0, bitsize, bitnum, bitregion_start,
-				 bitregion_end, value);
+				 bitregion_end, value, reverse);
 	  return true;
 	}
     }
@@ -898,6 +993,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
 
   extraction_insn insv;
   if (!MEM_P (op0)
+      && !reverse
       && get_best_reg_extraction_insn (&insv, EP_insv,
 				       GET_MODE_BITSIZE (GET_MODE (op0)),
 				       fieldmode)
@@ -906,7 +1002,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
 
   /* If OP0 is a memory, try copying it to a register and seeing if a
      cheap register alternative is available.  */
-  if (MEM_P (op0))
+  if (MEM_P (op0) && !reverse)
     {
       if (get_best_mem_extraction_insn (&insv, EP_insv, bitsize, bitnum,
 					fieldmode)
@@ -926,7 +1022,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
 	  rtx tempreg = copy_to_reg (xop0);
 	  if (store_bit_field_1 (tempreg, bitsize, bitpos,
 				 bitregion_start, bitregion_end,
-				 fieldmode, orig_value, false))
+				 fieldmode, orig_value, reverse, false))
 	    {
 	      emit_move_insn (xop0, tempreg);
 	      return true;
@@ -939,7 +1035,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
     return false;
 
   store_fixed_bit_field (op0, bitsize, bitnum, bitregion_start,
-			 bitregion_end, value);
+			 bitregion_end, value, reverse);
   return true;
 }
 
@@ -952,7 +1048,9 @@ store_bit_field_1 (rtx str_rtx, unsigned
    These two fields are 0, if the C++ memory model does not apply,
    or we are not interested in keeping track of bitfield regions.
 
-   FIELDMODE is the machine-mode of the FIELD_DECL node for this field.  */
+   FIELDMODE is the machine-mode of the FIELD_DECL node for this field.
+
+   If REVERSE is true, the store is to be done in reverse order.  */
 
 void
 store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
@@ -960,7 +1058,7 @@ store_bit_field (rtx str_rtx, unsigned H
 		 unsigned HOST_WIDE_INT bitregion_start,
 		 unsigned HOST_WIDE_INT bitregion_end,
 		 machine_mode fieldmode,
-		 rtx value)
+		 rtx value, bool reverse)
 {
   /* Handle -fstrict-volatile-bitfields in the cases where it applies.  */
   if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, fieldmode,
@@ -974,6 +1072,8 @@ store_bit_field (rtx str_rtx, unsigned H
 	{
 	  str_rtx = adjust_bitfield_address (str_rtx, fieldmode,
 					     bitnum / BITS_PER_UNIT);
+	  if (reverse)
+	    value = flip_storage_order (fieldmode, value);
 	  gcc_assert (bitnum % BITS_PER_UNIT == 0);
 	  emit_move_insn (str_rtx, value);
 	}
@@ -986,7 +1086,7 @@ store_bit_field (rtx str_rtx, unsigned H
 	  gcc_assert (bitnum + bitsize <= GET_MODE_BITSIZE (fieldmode));
 	  temp = copy_to_reg (str_rtx);
 	  if (!store_bit_field_1 (temp, bitsize, bitnum, 0, 0,
-				  fieldmode, value, true))
+				  fieldmode, value, reverse, true))
 	    gcc_unreachable ();
 
 	  emit_move_insn (str_rtx, temp);
@@ -1019,19 +1119,21 @@ store_bit_field (rtx str_rtx, unsigned H
 
   if (!store_bit_field_1 (str_rtx, bitsize, bitnum,
 			  bitregion_start, bitregion_end,
-			  fieldmode, value, true))
+			  fieldmode, value, reverse, true))
     gcc_unreachable ();
 }
 \f
 /* Use shifts and boolean operations to store VALUE into a bit field of
-   width BITSIZE in OP0, starting at bit BITNUM.  */
+   width BITSIZE in OP0, starting at bit BITNUM.
+
+   If REVERSE is true, the store is to be done in reverse order.  */
 
 static void
 store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
 		       unsigned HOST_WIDE_INT bitnum,
 		       unsigned HOST_WIDE_INT bitregion_start,
 		       unsigned HOST_WIDE_INT bitregion_end,
-		       rtx value)
+		       rtx value, bool reverse)
 {
   /* There is a case not handled here:
      a structure with a known alignment of just a halfword
@@ -1054,14 +1156,14 @@ store_fixed_bit_field (rtx op0, unsigned
 	  /* The only way this should occur is if the field spans word
 	     boundaries.  */
 	  store_split_bit_field (op0, bitsize, bitnum, bitregion_start,
-				 bitregion_end, value);
+				 bitregion_end, value, reverse);
 	  return;
 	}
 
       op0 = narrow_bit_field_mem (op0, mode, bitsize, bitnum, &bitnum);
     }
 
-  store_fixed_bit_field_1 (op0, bitsize, bitnum, value);
+  store_fixed_bit_field_1 (op0, bitsize, bitnum, value, reverse);
 }
 
 /* Helper function for store_fixed_bit_field, stores
@@ -1070,7 +1172,7 @@ store_fixed_bit_field (rtx op0, unsigned
 static void
 store_fixed_bit_field_1 (rtx op0, unsigned HOST_WIDE_INT bitsize,
 			 unsigned HOST_WIDE_INT bitnum,
-			 rtx value)
+			 rtx value, bool reverse)
 {
   machine_mode mode;
   rtx temp;
@@ -1083,7 +1185,7 @@ store_fixed_bit_field_1 (rtx op0, unsign
   /* Note that bitsize + bitnum can be greater than GET_MODE_BITSIZE (mode)
      for invalid input, such as f5 from gcc.dg/pr48335-2.c.  */
 
-  if (BYTES_BIG_ENDIAN)
+  if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
     /* BITNUM is the distance between our msb
        and that of the containing datum.
        Convert it to the distance from the lsb.  */
@@ -1129,6 +1231,9 @@ store_fixed_bit_field_1 (rtx op0, unsign
 			      bitnum, NULL_RTX, 1);
     }
 
+  if (reverse)
+    value = flip_storage_order (mode, value);
+
   /* Now clear the chosen bits in OP0,
      except that if VALUE is -1 we need not bother.  */
   /* We keep the intermediates in registers to allow CSE to combine
@@ -1138,8 +1243,10 @@ store_fixed_bit_field_1 (rtx op0, unsign
 
   if (! all_one)
     {
-      temp = expand_binop (mode, and_optab, temp,
-			   mask_rtx (mode, bitnum, bitsize, 1),
+      rtx mask = mask_rtx (mode, bitnum, bitsize, 1);
+      if (reverse)
+	mask = flip_storage_order (mode, mask);
+      temp = expand_binop (mode, and_optab, temp, mask,
 			   NULL_RTX, 1, OPTAB_LIB_WIDEN);
       temp = force_reg (mode, temp);
     }
@@ -1167,6 +1274,8 @@ store_fixed_bit_field_1 (rtx op0, unsign
    (within the word).
    VALUE is the value to store.
 
+   If REVERSE is true, the store is to be done in reverse order.
+
    This does not yet handle fields wider than BITS_PER_WORD.  */
 
 static void
@@ -1174,10 +1283,9 @@ store_split_bit_field (rtx op0, unsigned
 		       unsigned HOST_WIDE_INT bitpos,
 		       unsigned HOST_WIDE_INT bitregion_start,
 		       unsigned HOST_WIDE_INT bitregion_end,
-		       rtx value)
+		       rtx value, bool reverse)
 {
-  unsigned int unit;
-  unsigned int bitsdone = 0;
+  unsigned int unit, total_bits, bitsdone = 0;
 
   /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
      much at a time.  */
@@ -1208,12 +1316,14 @@ store_split_bit_field (rtx op0, unsigned
 					       : word_mode, value));
     }
 
+  total_bits = GET_MODE_BITSIZE (GET_MODE (value));
+
   while (bitsdone < bitsize)
     {
       unsigned HOST_WIDE_INT thissize;
-      rtx part, word;
       unsigned HOST_WIDE_INT thispos;
       unsigned HOST_WIDE_INT offset;
+      rtx part, word;
 
       offset = (bitpos + bitsdone) / unit;
       thispos = (bitpos + bitsdone) % unit;
@@ -1238,13 +1348,18 @@ store_split_bit_field (rtx op0, unsigned
       thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
       thissize = MIN (thissize, unit - thispos);
 
-      if (BYTES_BIG_ENDIAN)
+      if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
 	{
 	  /* Fetch successively less significant portions.  */
 	  if (CONST_INT_P (value))
 	    part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value))
 			     >> (bitsize - bitsdone - thissize))
 			    & (((HOST_WIDE_INT) 1 << thissize) - 1));
+          /* Likewise, but the source is little-endian.  */
+          else if (reverse)
+	    part = extract_fixed_bit_field (word_mode, value, thissize,
+					    bitsize - bitsdone - thissize,
+					    NULL_RTX, 1, false);
 	  else
 	    {
 	      int total_bits = GET_MODE_BITSIZE (GET_MODE (value));
@@ -1253,7 +1368,7 @@ store_split_bit_field (rtx op0, unsigned
 		 endianness compensation) to fetch the piece we want.  */
 	      part = extract_fixed_bit_field (word_mode, value, thissize,
 					      total_bits - bitsize + bitsdone,
-					      NULL_RTX, 1);
+					      NULL_RTX, 1, false);
 	    }
 	}
       else
@@ -1263,9 +1378,14 @@ store_split_bit_field (rtx op0, unsigned
 	    part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value))
 			     >> bitsdone)
 			    & (((HOST_WIDE_INT) 1 << thissize) - 1));
+	  /* Likewise, but the source is big-endian.  */
+          else if (reverse)
+	    part = extract_fixed_bit_field (word_mode, value, thissize,
+					    total_bits - bitsdone - thissize,
+					    NULL_RTX, 1, false);
 	  else
 	    part = extract_fixed_bit_field (word_mode, value, thissize,
-					    bitsdone, NULL_RTX, 1);
+					    bitsdone, NULL_RTX, 1, false);
 	}
 
       /* If OP0 is a register, then handle OFFSET here.
@@ -1303,7 +1423,8 @@ store_split_bit_field (rtx op0, unsigned
 	 it is just an out-of-bounds access.  Ignore it.  */
       if (word != const0_rtx)
 	store_fixed_bit_field (word, thissize, offset * unit + thispos,
-			       bitregion_start, bitregion_end, part);
+			       bitregion_start, bitregion_end, part,
+			       reverse);
       bitsdone += thissize;
     }
 }
@@ -1428,7 +1549,7 @@ static rtx
 extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
 		     unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
 		     machine_mode mode, machine_mode tmode,
-		     bool fallback_p)
+		     bool reverse, bool fallback_p)
 {
   rtx op0 = str_rtx;
   machine_mode int_mode;
@@ -1454,6 +1575,8 @@ extract_bit_field_1 (rtx str_rtx, unsign
       && bitnum == 0
       && bitsize == GET_MODE_BITSIZE (GET_MODE (op0)))
     {
+      if (reverse)
+	op0 = flip_storage_order (mode, op0);
       /* We're trying to extract a full register from itself.  */
       return op0;
     }
@@ -1570,6 +1693,7 @@ extract_bit_field_1 (rtx str_rtx, unsign
      as the least significant bit of the value is the least significant
      bit of either OP0 or a word of OP0.  */
   if (!MEM_P (op0)
+      && !reverse
       && lowpart_bit_field_p (bitnum, bitsize, GET_MODE (op0))
       && bitsize == GET_MODE_BITSIZE (mode1)
       && TRULY_NOOP_TRUNCATION_MODES_P (mode1, GET_MODE (op0)))
@@ -1585,6 +1709,8 @@ extract_bit_field_1 (rtx str_rtx, unsign
   if (simple_mem_bitfield_p (op0, bitsize, bitnum, mode1))
     {
       op0 = adjust_bitfield_address (op0, mode1, bitnum / BITS_PER_UNIT);
+      if (reverse)
+	op0 = flip_storage_order (mode1, op0);
       return convert_extracted_bit_field (op0, mode, tmode, unsignedp);
     }
 
@@ -1597,7 +1723,7 @@ extract_bit_field_1 (rtx str_rtx, unsign
 	 This is because the most significant word is the one which may
 	 be less than full.  */
 
-      unsigned int backwards = WORDS_BIG_ENDIAN;
+      const bool backwards = WORDS_BIG_ENDIAN;
       unsigned int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
       unsigned int i;
       rtx_insn *last;
@@ -1624,7 +1750,7 @@ extract_bit_field_1 (rtx str_rtx, unsign
 	       ? GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD - i - 1
 	       : i);
 	  /* Offset from start of field in OP0.  */
-	  unsigned int bit_offset = (backwards
+	  unsigned int bit_offset = (backwards ^ reverse
 				     ? MAX ((int) bitsize - ((int) i + 1)
 					    * BITS_PER_WORD,
 					    0)
@@ -1634,7 +1760,7 @@ extract_bit_field_1 (rtx str_rtx, unsign
 	    = extract_bit_field_1 (op0, MIN (BITS_PER_WORD,
 					     bitsize - i * BITS_PER_WORD),
 				   bitnum + bit_offset, 1, target_part,
-				   mode, word_mode, fallback_p);
+				   mode, word_mode, reverse, fallback_p);
 
 	  gcc_assert (target_part);
 	  if (!result_part)
@@ -1684,7 +1810,8 @@ extract_bit_field_1 (rtx str_rtx, unsign
 	{
 	  if (!fallback_p)
 	    return NULL_RTX;
-	  target = extract_split_bit_field (op0, bitsize, bitnum, unsignedp);
+	  target = extract_split_bit_field (op0, bitsize, bitnum, unsignedp,
+					    reverse);
 	  return convert_extracted_bit_field (target, mode, tmode, unsignedp);
 	}
     }
@@ -1694,6 +1821,7 @@ extract_bit_field_1 (rtx str_rtx, unsign
   enum extraction_pattern pattern = unsignedp ? EP_extzv : EP_extv;
   extraction_insn extv;
   if (!MEM_P (op0)
+      && !reverse
       /* ??? We could limit the structure size to the part of OP0 that
 	 contains the field, with appropriate checks for endianness
 	 and TRULY_NOOP_TRUNCATION.  */
@@ -1710,7 +1838,7 @@ extract_bit_field_1 (rtx str_rtx, unsign
 
   /* If OP0 is a memory, try copying it to a register and seeing if a
      cheap register alternative is available.  */
-  if (MEM_P (op0))
+  if (MEM_P (op0) & !reverse)
     {
       if (get_best_mem_extraction_insn (&extv, pattern, bitsize, bitnum,
 					tmode))
@@ -1735,7 +1863,7 @@ extract_bit_field_1 (rtx str_rtx, unsign
 	  xop0 = copy_to_reg (xop0);
 	  rtx result = extract_bit_field_1 (xop0, bitsize, bitpos,
 					    unsignedp, target,
-					    mode, tmode, false);
+					    mode, tmode, reverse, false);
 	  if (result)
 	    return result;
 	  delete_insns_since (last);
@@ -1753,9 +1881,21 @@ extract_bit_field_1 (rtx str_rtx, unsign
   /* Should probably push op0 out to memory and then do a load.  */
   gcc_assert (int_mode != BLKmode);
 
-  target = extract_fixed_bit_field (int_mode, op0, bitsize, bitnum,
-				    target, unsignedp);
-  return convert_extracted_bit_field (target, mode, tmode, unsignedp);
+  target = extract_fixed_bit_field (int_mode, op0, bitsize, bitnum, target,
+				    unsignedp, reverse);
+
+  /* Complex values must be reversed piecewise, so we need to undo the global
+     reversal, convert to the complex mode and reverse again.  */
+  if (reverse && COMPLEX_MODE_P (tmode))
+    {
+      target = flip_storage_order (int_mode, target);
+      target = convert_extracted_bit_field (target, mode, tmode, unsignedp);
+      target = flip_storage_order (tmode, target);
+    }
+  else
+    target = convert_extracted_bit_field (target, mode, tmode, unsignedp);
+
+  return target;
 }
 
 /* Generate code to extract a byte-field from STR_RTX
@@ -1769,6 +1909,8 @@ extract_bit_field_1 (rtx str_rtx, unsign
    TMODE is the mode the caller would like the value to have;
    but the value may be returned with type MODE instead.
 
+   If REVERSE is true, the extraction is to be done in reverse order.
+
    If a TARGET is specified and we can store in it at no extra cost,
    we do so, and return TARGET.
    Otherwise, we return a REG of mode TMODE or MODE, with TMODE preferred
@@ -1777,7 +1919,7 @@ extract_bit_field_1 (rtx str_rtx, unsign
 rtx
 extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
 		   unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
-		   machine_mode mode, machine_mode tmode)
+		   machine_mode mode, machine_mode tmode, bool reverse)
 {
   machine_mode mode1;
 
@@ -1799,6 +1941,8 @@ extract_bit_field (rtx str_rtx, unsigned
 	{
 	  rtx result = adjust_bitfield_address (str_rtx, mode1,
 						bitnum / BITS_PER_UNIT);
+	  if (reverse)
+	    result = flip_storage_order (mode1, result);
 	  gcc_assert (bitnum % BITS_PER_UNIT == 0);
 	  return convert_extracted_bit_field (result, mode, tmode, unsignedp);
 	}
@@ -1810,13 +1954,15 @@ extract_bit_field (rtx str_rtx, unsigned
     }
 
   return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp,
-			      target, mode, tmode, true);
+			      target, mode, tmode, reverse, true);
 }
 \f
 /* Use shifts and boolean operations to extract a field of BITSIZE bits
    from bit BITNUM of OP0.
 
    UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value).
+   If REVERSE is true, the extraction is to be done in reverse order.
+
    If TARGET is nonzero, attempts to store the value there
    and return TARGET, but this is not guaranteed.
    If TARGET is not used, create a pseudo-reg of mode TMODE for the value.  */
@@ -1825,7 +1971,7 @@ static rtx
 extract_fixed_bit_field (machine_mode tmode, rtx op0,
 			 unsigned HOST_WIDE_INT bitsize,
 			 unsigned HOST_WIDE_INT bitnum, rtx target,
-			 int unsignedp)
+			 int unsignedp, bool reverse)
 {
   if (MEM_P (op0))
     {
@@ -1836,13 +1982,14 @@ extract_fixed_bit_field (machine_mode tm
       if (mode == VOIDmode)
 	/* The only way this should occur is if the field spans word
 	   boundaries.  */
-	return extract_split_bit_field (op0, bitsize, bitnum, unsignedp);
+	return extract_split_bit_field (op0, bitsize, bitnum, unsignedp,
+					reverse);
 
       op0 = narrow_bit_field_mem (op0, mode, bitsize, bitnum, &bitnum);
     }
 
   return extract_fixed_bit_field_1 (tmode, op0, bitsize, bitnum,
-				    target, unsignedp);
+				    target, unsignedp, reverse);
 }
 
 /* Helper function for extract_fixed_bit_field, extracts
@@ -1852,7 +1999,7 @@ static rtx
 extract_fixed_bit_field_1 (machine_mode tmode, rtx op0,
 			   unsigned HOST_WIDE_INT bitsize,
 			   unsigned HOST_WIDE_INT bitnum, rtx target,
-			   int unsignedp)
+			   int unsignedp, bool reverse)
 {
   machine_mode mode = GET_MODE (op0);
   gcc_assert (SCALAR_INT_MODE_P (mode));
@@ -1861,13 +2008,15 @@ extract_fixed_bit_field_1 (machine_mode
      for invalid input, such as extract equivalent of f5 from
      gcc.dg/pr48335-2.c.  */
 
-  if (BYTES_BIG_ENDIAN)
+  if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
     /* BITNUM is the distance between our msb and that of OP0.
        Convert it to the distance from the lsb.  */
     bitnum = GET_MODE_BITSIZE (mode) - bitsize - bitnum;
 
   /* Now BITNUM is always the distance between the field's lsb and that of OP0.
      We have reduced the big-endian case to the little-endian case.  */
+  if (reverse)
+    op0 = flip_storage_order (mode, op0);
 
   if (unsignedp)
     {
@@ -1939,11 +2088,14 @@ lshift_value (machine_mode mode, unsigne
 
    OP0 is the REG, SUBREG or MEM rtx for the first of the two words.
    BITSIZE is the field width; BITPOS, position of its first bit, in the word.
-   UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend.  */
+   UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend.
+
+   If REVERSE is true, the extraction is to be done in reverse order.  */
 
 static rtx
 extract_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
-			 unsigned HOST_WIDE_INT bitpos, int unsignedp)
+			 unsigned HOST_WIDE_INT bitpos, int unsignedp,
+			 bool reverse)
 {
   unsigned int unit;
   unsigned int bitsdone = 0;
@@ -1998,11 +2150,11 @@ extract_split_bit_field (rtx op0, unsign
 	 whose meaning is determined by BYTES_PER_UNIT.
 	 OFFSET is in UNITs, and UNIT is in bits.  */
       part = extract_fixed_bit_field (word_mode, word, thissize,
-				      offset * unit + thispos, 0, 1);
+				      offset * unit + thispos, 0, 1, reverse);
       bitsdone += thissize;
 
       /* Shift this part into place for the result.  */
-      if (BYTES_BIG_ENDIAN)
+      if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
 	{
 	  if (bitsize != bitsdone)
 	    part = expand_shift (LSHIFT_EXPR, word_mode, part,
Index: expmed.h
===================================================================
--- expmed.h	(.../trunk/gcc)	(revision 228112)
+++ expmed.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -676,6 +676,10 @@ extern rtx emit_cstore (rtx target, enum
    May emit insns.  */
 extern rtx negate_rtx (machine_mode, rtx);
 
+/* Arguments MODE, RTX: return an rtx for the flipping of that value.
+   May emit insns.  */
+extern rtx flip_storage_order (enum machine_mode, rtx);
+
 /* Expand a logical AND operation.  */
 extern rtx expand_and (machine_mode, rtx, rtx, rtx);
 
@@ -707,10 +711,10 @@ extern void store_bit_field (rtx, unsign
 			     unsigned HOST_WIDE_INT,
 			     unsigned HOST_WIDE_INT,
 			     unsigned HOST_WIDE_INT,
-			     machine_mode, rtx);
+			     machine_mode, rtx, bool);
 extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT,
 			      unsigned HOST_WIDE_INT, int, rtx,
-			      machine_mode, machine_mode);
+			      machine_mode, machine_mode, bool);
 extern rtx extract_low_bits (machine_mode, machine_mode, rtx);
 extern rtx expand_mult (machine_mode, rtx, rtx, rtx, int);
 extern rtx expand_mult_highpart_adjust (machine_mode, rtx, rtx, rtx, rtx, int);
Index: tree-dfa.c
===================================================================
--- tree-dfa.c	(.../trunk/gcc)	(revision 228112)
+++ tree-dfa.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -383,12 +383,14 @@ get_or_create_ssa_default_def (struct fu
    base variable.  The access range is delimited by bit positions *POFFSET and
    *POFFSET + *PMAX_SIZE.  The access size is *PSIZE bits.  If either
    *PSIZE or *PMAX_SIZE is -1, they could not be determined.  If *PSIZE
-   and *PMAX_SIZE are equal, the access is non-variable.  */
+   and *PMAX_SIZE are equal, the access is non-variable.  If *PREVERSE is
+   true, the storage order of the reference is reversed.  */
 
 tree
 get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
 			 HOST_WIDE_INT *psize,
-			 HOST_WIDE_INT *pmax_size)
+			 HOST_WIDE_INT *pmax_size,
+			 bool *preverse)
 {
   offset_int bitsize = -1;
   offset_int maxsize;
@@ -396,7 +398,8 @@ get_ref_base_and_extent (tree exp, HOST_
   offset_int bit_offset = 0;
   bool seen_variable_array_ref = false;
 
-  /* First get the final access size from just the outermost expression.  */
+  /* First get the final access size and the storage order from just the
+     outermost expression.  */
   if (TREE_CODE (exp) == COMPONENT_REF)
     size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
   else if (TREE_CODE (exp) == BIT_FIELD_REF)
@@ -413,6 +416,8 @@ get_ref_base_and_extent (tree exp, HOST_
       && TREE_CODE (size_tree) == INTEGER_CST)
     bitsize = wi::to_offset (size_tree);
 
+  *preverse = reverse_storage_order_for_component_p (exp);
+
   /* Initially, maxsize is the same as the accessed element size.
      In the following it will only grow (or become -1).  */
   maxsize = bitsize;
Index: tree-dfa.h
===================================================================
--- tree-dfa.h	(.../trunk/gcc)	(revision 228112)
+++ tree-dfa.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -30,7 +30,7 @@ extern tree ssa_default_def (struct func
 extern void set_ssa_default_def (struct function *, tree, tree);
 extern tree get_or_create_ssa_default_def (struct function *, tree);
 extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
-				     HOST_WIDE_INT *, HOST_WIDE_INT *);
+				     HOST_WIDE_INT *, HOST_WIDE_INT *, bool *);
 extern tree get_addr_base_and_unit_offset_1 (tree, HOST_WIDE_INT *,
 					     tree (*) (tree));
 extern tree get_addr_base_and_unit_offset (tree, HOST_WIDE_INT *);
Index: lto/lto.c
===================================================================
--- lto/lto.c	(.../trunk/gcc)	(revision 228112)
+++ lto/lto.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1019,7 +1019,10 @@ compare_tree_sccs_1 (tree t1, tree t2, t
   compare_values (TREE_DEPRECATED);
   if (TYPE_P (t1))
     {
-      compare_values (TYPE_SATURATING);
+      if (AGGREGATE_TYPE_P (t1))
+	compare_values (TYPE_REVERSE_STORAGE_ORDER);
+      else
+	compare_values (TYPE_SATURATING);
       compare_values (TYPE_ADDR_SPACE);
     }
   else if (code == SSA_NAME)
Index: tree-streamer-out.c
===================================================================
--- tree-streamer-out.c	(.../trunk/gcc)	(revision 228112)
+++ tree-streamer-out.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -114,9 +114,14 @@ pack_ts_base_value_fields (struct bitpac
   bp_pack_value (bp, TREE_DEPRECATED (expr), 1);
   if (TYPE_P (expr))
     {
-      bp_pack_value (bp, TYPE_SATURATING (expr), 1);
+      if (AGGREGATE_TYPE_P (expr))
+	bp_pack_value (bp, TYPE_REVERSE_STORAGE_ORDER (expr), 1);
+      else
+	bp_pack_value (bp, TYPE_SATURATING (expr), 1);
       bp_pack_value (bp, TYPE_ADDR_SPACE (expr), 8);
     }
+  else if (TREE_CODE (expr) == BIT_FIELD_REF || TREE_CODE (expr) == MEM_REF)
+    bp_pack_value (bp, REF_REVERSE_STORAGE_ORDER (expr), 1);
   else if (TREE_CODE (expr) == SSA_NAME)
     {
       bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1);
Index: print-tree.c
===================================================================
--- print-tree.c	(.../trunk/gcc)	(revision 228112)
+++ print-tree.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -570,6 +570,13 @@ print_node (FILE *file, const char *pref
       if (TYPE_NEEDS_CONSTRUCTING (node))
 	fputs (" needs-constructing", file);
 
+      if ((code == RECORD_TYPE
+	   || code == UNION_TYPE
+	   || code == QUAL_UNION_TYPE
+	   || code == ARRAY_TYPE)
+	  && TYPE_REVERSE_STORAGE_ORDER (node))
+	fputs (" reverse-storage-order", file);
+
       /* The transparent-union flag is used for different things in
 	 different nodes.  */
       if ((code == UNION_TYPE || code == RECORD_TYPE)
Index: varasm.c
===================================================================
--- varasm.c	(.../trunk/gcc)	(revision 228112)
+++ varasm.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -115,7 +115,7 @@ static int compare_constant (const tree,
 static void output_constant_def_contents (rtx);
 static void output_addressed_constants (tree);
 static unsigned HOST_WIDE_INT output_constant (tree, unsigned HOST_WIDE_INT,
-					       unsigned int);
+					       unsigned int, bool);
 static void globalize_decl (tree);
 static bool decl_readonly_section_1 (enum section_category);
 #ifdef BSS_SECTION_ASM_OP
@@ -2062,7 +2062,8 @@ assemble_variable_contents (tree decl, c
 	/* Output the actual data.  */
 	output_constant (DECL_INITIAL (decl),
 			 tree_to_uhwi (DECL_SIZE_UNIT (decl)),
-			 get_variable_align (decl));
+			 get_variable_align (decl),
+			 false);
       else
 	/* Leave space for it.  */
 	assemble_zeros (tree_to_uhwi (DECL_SIZE_UNIT (decl)));
@@ -2788,11 +2789,12 @@ assemble_integer (rtx x, unsigned int si
 }
 \f
 void
-assemble_real (REAL_VALUE_TYPE d, machine_mode mode, unsigned int align)
+assemble_real (REAL_VALUE_TYPE d, machine_mode mode, unsigned int align,
+	       bool reverse)
 {
   long data[4] = {0, 0, 0, 0};
-  int i;
   int bitsize, nelts, nunits, units_per;
+  rtx elt;
 
   /* This is hairy.  We have a quantity of known size.  real_to_target
      will put it into an array of *host* longs, 32 bits per element
@@ -2814,15 +2816,24 @@ assemble_real (REAL_VALUE_TYPE d, machin
   real_to_target (data, &d, mode);
 
   /* Put out the first word with the specified alignment.  */
-  assemble_integer (GEN_INT (data[0]), MIN (nunits, units_per), align, 1);
+  if (reverse)
+    elt = flip_storage_order (SImode, gen_int_mode (data[nelts - 1], SImode));
+  else
+    elt = GEN_INT (data[0]);
+  assemble_integer (elt, MIN (nunits, units_per), align, 1);
   nunits -= units_per;
 
   /* Subsequent words need only 32-bit alignment.  */
   align = min_align (align, 32);
 
-  for (i = 1; i < nelts; i++)
+  for (int i = 1; i < nelts; i++)
     {
-      assemble_integer (GEN_INT (data[i]), MIN (nunits, units_per), align, 1);
+      if (reverse)
+	elt = flip_storage_order (SImode,
+				  gen_int_mode (data[nelts - 1 - i], SImode));
+      else
+	elt = GEN_INT (data[i]);
+      assemble_integer (elt, MIN (nunits, units_per), align, 1);
       nunits -= units_per;
     }
 }
@@ -3124,10 +3135,12 @@ compare_constant (const tree t1, const t
 	if (typecode == ARRAY_TYPE)
 	  {
 	    HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1));
-	    /* For arrays, check that the sizes all match.  */
+	    /* For arrays, check that mode, size and storage order match.  */
 	    if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
 		|| size_1 == -1
-		|| size_1 != int_size_in_bytes (TREE_TYPE (t2)))
+		|| size_1 != int_size_in_bytes (TREE_TYPE (t2))
+		|| TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (t1))
+		   != TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (t2)))
 	      return 0;
 	  }
 	else
@@ -3411,7 +3424,7 @@ assemble_constant_contents (tree exp, co
   targetm.asm_out.declare_constant_name (asm_out_file, label, exp, size);
 
   /* Output the value of EXP.  */
-  output_constant (exp, size, align);
+  output_constant (exp, size, align, false);
 
   targetm.asm_out.decl_end ();
 }
@@ -3845,7 +3858,7 @@ output_constant_pool_2 (machine_mode mod
 
 	gcc_assert (CONST_DOUBLE_AS_FLOAT_P (x));
 	REAL_VALUE_FROM_CONST_DOUBLE (r, x);
-	assemble_real (r, mode, align);
+	assemble_real (r, mode, align, false);
 	break;
       }
 
@@ -4345,7 +4358,11 @@ initializer_constant_valid_p_1 (tree val
 	      tree reloc;
 	      reloc = initializer_constant_valid_p_1 (elt, TREE_TYPE (elt),
 						      NULL);
-	      if (!reloc)
+	      if (!reloc
+		  /* An absolute value is required with reverse SSO.  */
+		  || (reloc != null_pointer_node
+		      && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (value))
+		      && !AGGREGATE_TYPE_P (TREE_TYPE (elt))))
 		{
 		  if (cache)
 		    {
@@ -4585,9 +4602,19 @@ initializer_constant_valid_p_1 (tree val
    therefore, we do not need to check for such things as
    arithmetic-combinations of integers.  */
 tree
-initializer_constant_valid_p (tree value, tree endtype)
+initializer_constant_valid_p (tree value, tree endtype, bool reverse)
 {
-  return initializer_constant_valid_p_1 (value, endtype, NULL);
+  tree reloc = initializer_constant_valid_p_1 (value, endtype, NULL);
+
+  /* An absolute value is required with reverse storage order.  */
+  if (reloc
+      && reloc != null_pointer_node
+      && reverse
+      && !AGGREGATE_TYPE_P (endtype)
+      && !VECTOR_TYPE_P (endtype))
+    reloc = NULL_TREE;
+
+  return reloc;
 }
 \f
 /* Return true if VALUE is a valid constant-valued expression
@@ -4637,8 +4664,8 @@ struct oc_outer_state {
 };
 
 static unsigned HOST_WIDE_INT
-  output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int,
-		      oc_outer_state *);
+output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int, bool,
+		    oc_outer_state *);
 
 /* Output assembler code for constant EXP, with no label.
    This includes the pseudo-op such as ".int" or ".byte", and a newline.
@@ -4660,13 +4687,18 @@ static unsigned HOST_WIDE_INT
    for a structure constructor that wants to produce more than SIZE bytes.
    But such constructors will never be generated for any possible input.
 
-   ALIGN is the alignment of the data in bits.  */
+   ALIGN is the alignment of the data in bits.
+
+   If REVERSE is true, EXP is interpreted in reverse storage order wrt the
+   target order.  */
 
 static unsigned HOST_WIDE_INT
-output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
+output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align,
+		 bool reverse)
 {
   enum tree_code code;
   unsigned HOST_WIDE_INT thissize;
+  rtx cst;
 
   if (size == 0 || flag_syntax_only)
     return size;
@@ -4761,9 +4793,10 @@ output_constant (tree exp, unsigned HOST
     case FIXED_POINT_TYPE:
     case POINTER_BOUNDS_TYPE:
     case NULLPTR_TYPE:
-      if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode,
-					   EXPAND_INITIALIZER),
-			      MIN (size, thissize), align, 0))
+      cst = expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
+      if (reverse)
+	cst = flip_storage_order (TYPE_MODE (TREE_TYPE (exp)), cst);
+      if (!assemble_integer (cst, MIN (size, thissize), align, 0))
 	error ("initializer for integer/fixed-point value is too complicated");
       break;
 
@@ -4771,13 +4804,17 @@ output_constant (tree exp, unsigned HOST
       if (TREE_CODE (exp) != REAL_CST)
 	error ("initializer for floating value is not a floating constant");
       else
-	assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align);
+	{
+	  assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)),
+			 align, reverse);
+	}
       break;
 
     case COMPLEX_TYPE:
-      output_constant (TREE_REALPART (exp), thissize / 2, align);
+      output_constant (TREE_REALPART (exp), thissize / 2, align, reverse);
       output_constant (TREE_IMAGPART (exp), thissize / 2,
-		       min_align (align, BITS_PER_UNIT * (thissize / 2)));
+		       min_align (align, BITS_PER_UNIT * (thissize / 2)),
+		       reverse);
       break;
 
     case ARRAY_TYPE:
@@ -4785,7 +4822,7 @@ output_constant (tree exp, unsigned HOST
       switch (TREE_CODE (exp))
 	{
 	case CONSTRUCTOR:
-	  return output_constructor (exp, size, align, NULL);
+	  return output_constructor (exp, size, align, reverse, NULL);
 	case STRING_CST:
 	  thissize
 	    = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp), size);
@@ -4796,11 +4833,13 @@ output_constant (tree exp, unsigned HOST
 	    machine_mode inner = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
 	    unsigned int nalign = MIN (align, GET_MODE_ALIGNMENT (inner));
 	    int elt_size = GET_MODE_SIZE (inner);
-	    output_constant (VECTOR_CST_ELT (exp, 0), elt_size, align);
+	    output_constant (VECTOR_CST_ELT (exp, 0), elt_size, align,
+			     reverse);
 	    thissize = elt_size;
 	    for (unsigned int i = 1; i < VECTOR_CST_NELTS (exp); i++)
 	      {
-		output_constant (VECTOR_CST_ELT (exp, i), elt_size, nalign);
+		output_constant (VECTOR_CST_ELT (exp, i), elt_size, nalign,
+				 reverse);
 		thissize += elt_size;
 	      }
 	    break;
@@ -4813,7 +4852,7 @@ output_constant (tree exp, unsigned HOST
     case RECORD_TYPE:
     case UNION_TYPE:
       gcc_assert (TREE_CODE (exp) == CONSTRUCTOR);
-      return output_constructor (exp, size, align, NULL);
+      return output_constructor (exp, size, align, reverse, NULL);
 
     case ERROR_MARK:
       return 0;
@@ -4827,7 +4866,6 @@ output_constant (tree exp, unsigned HOST
 
   return size;
 }
-
 \f
 /* Subroutine of output_constructor, used for computing the size of
    arrays of unspecified length.  VAL must be a CONSTRUCTOR of an array
@@ -4889,6 +4927,7 @@ struct oc_local_state {
   int last_relative_index;    /* Implicit or explicit index of the last
 				 array element output within a bitfield.  */
   bool byte_buffer_in_use;    /* Whether BYTE is in use.  */
+  bool reverse;               /* Whether reverse storage order is in use.  */
 
   /* Current element.  */
   tree field;      /* Current field decl in a record.  */
@@ -4921,7 +4960,8 @@ output_constructor_array_range (oc_local
       if (local->val == NULL_TREE)
 	assemble_zeros (fieldsize);
       else
-	fieldsize = output_constant (local->val, fieldsize, align2);
+	fieldsize
+	  = output_constant (local->val, fieldsize, align2, local->reverse);
 
       /* Count its size.  */
       local->total_bytes += fieldsize;
@@ -5007,7 +5047,8 @@ output_constructor_regular_field (oc_loc
   if (local->val == NULL_TREE)
     assemble_zeros (fieldsize);
   else
-    fieldsize = output_constant (local->val, fieldsize, align2);
+    fieldsize
+      = output_constant (local->val, fieldsize, align2, local->reverse);
 
   /* Count its size.  */
   local->total_bytes += fieldsize;
@@ -5105,7 +5146,7 @@ output_constructor_bitfield (oc_local_st
       temp_state.bit_offset = next_offset % BITS_PER_UNIT;
       temp_state.byte = local->byte;
       local->total_bytes
-	  += output_constructor (local->val, 0, 0, &temp_state);
+	+= output_constructor (local->val, 0, 0, local->reverse, &temp_state);
       local->byte = temp_state.byte;
       return;
     }
@@ -5131,7 +5172,7 @@ output_constructor_bitfield (oc_local_st
 
       /* Number of bits we can process at once (all part of the same byte).  */
       this_time = MIN (end_offset - next_offset, BITS_PER_UNIT - next_bit);
-      if (BYTES_BIG_ENDIAN)
+      if (local->reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
 	{
 	  /* On big-endian machine, take the most significant bits (of the
 	     bits that are significant) first and put them into bytes from
@@ -5195,12 +5236,11 @@ output_constructor_bitfield (oc_local_st
    caller output state of relevance in recursive invocations.  */
 
 static unsigned HOST_WIDE_INT
-output_constructor (tree exp, unsigned HOST_WIDE_INT size,
-		    unsigned int align, oc_outer_state *outer)
+output_constructor (tree exp, unsigned HOST_WIDE_INT size, unsigned int align,
+		    bool reverse, oc_outer_state *outer)
 {
   unsigned HOST_WIDE_INT cnt;
   constructor_elt *ce;
-
   oc_local_state local;
 
   /* Setup our local state to communicate with helpers.  */
@@ -5217,6 +5257,11 @@ output_constructor (tree exp, unsigned H
   local.byte_buffer_in_use = outer != NULL;
   local.byte = outer ? outer->byte : 0;
   local.last_relative_index = -1;
+  /* The storage order is specified for every aggregate type.  */
+  if (AGGREGATE_TYPE_P (local.type))
+    local.reverse = TYPE_REVERSE_STORAGE_ORDER (local.type);
+  else
+    local.reverse = reverse;
 
   gcc_assert (HOST_BITS_PER_WIDE_INT >= BITS_PER_UNIT);
 
Index: varasm.h
===================================================================
--- varasm.h	(.../trunk/gcc)	(revision 228112)
+++ varasm.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -60,7 +60,7 @@ extern void assemble_alias (tree, tree);
    We assume that VALUE has been folded as much as possible;
    therefore, we do not need to check for such things as
    arithmetic-combinations of integers.  */
-extern tree initializer_constant_valid_p (tree, tree);
+extern tree initializer_constant_valid_p (tree, tree, bool = false);
 
 /* Return true if VALUE is a valid constant-valued expression
    for use in initializing a static bit-field; one that can be
Index: tree-inline.c
===================================================================
--- tree-inline.c	(.../trunk/gcc)	(revision 228112)
+++ tree-inline.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -967,6 +967,7 @@ remap_gimple_op_r (tree *tp, int *walk_s
 	      && (!is_parm (TREE_OPERAND (old, 0))
 		  || (!id->transform_parameter && is_parm (ptr))))
 	    TREE_THIS_NOTRAP (*tp) = 1;
+	  REF_REVERSE_STORAGE_ORDER (*tp) = REF_REVERSE_STORAGE_ORDER (old);
 	  *walk_subtrees = 0;
 	  return NULL;
 	}
@@ -1224,6 +1225,7 @@ copy_tree_body_r (tree *tp, int *walk_su
 	      && (!is_parm (TREE_OPERAND (old, 0))
 		  || (!id->transform_parameter && is_parm (ptr))))
 	    TREE_THIS_NOTRAP (*tp) = 1;
+	  REF_REVERSE_STORAGE_ORDER (*tp) = REF_REVERSE_STORAGE_ORDER (old);
 	  *walk_subtrees = 0;
 	  return NULL;
 	}
Index: tree-streamer-in.c
===================================================================
--- tree-streamer-in.c	(.../trunk/gcc)	(revision 228112)
+++ tree-streamer-in.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -142,9 +142,14 @@ unpack_ts_base_value_fields (struct bitp
   TREE_DEPRECATED (expr) = (unsigned) bp_unpack_value (bp, 1);
   if (TYPE_P (expr))
     {
-      TYPE_SATURATING (expr) = (unsigned) bp_unpack_value (bp, 1);
+      if (AGGREGATE_TYPE_P (expr))
+	TYPE_REVERSE_STORAGE_ORDER (expr) = (unsigned) bp_unpack_value (bp, 1);
+      else
+	TYPE_SATURATING (expr) = (unsigned) bp_unpack_value (bp, 1);
       TYPE_ADDR_SPACE (expr) = (unsigned) bp_unpack_value (bp, 8);
     }
+  else if (TREE_CODE (expr) == BIT_FIELD_REF || TREE_CODE (expr) == MEM_REF)
+    REF_REVERSE_STORAGE_ORDER (expr) = (unsigned) bp_unpack_value (bp, 1);
   else if (TREE_CODE (expr) == SSA_NAME)
     {
       SSA_NAME_IS_DEFAULT_DEF (expr) = (unsigned) bp_unpack_value (bp, 1);
Index: output.h
===================================================================
--- output.h	(.../trunk/gcc)	(revision 228112)
+++ output.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -280,7 +280,7 @@ extern section *get_named_text_section (
 
 #ifdef REAL_VALUE_TYPE_SIZE
 /* Assemble the floating-point constant D into an object of size MODE.  */
-extern void assemble_real (REAL_VALUE_TYPE, machine_mode, unsigned);
+extern void assemble_real (REAL_VALUE_TYPE, machine_mode, unsigned, bool);
 #endif
 
 /* Write the address of the entity given by SYMBOL to SEC.  */
Index: tree-outof-ssa.c
===================================================================
--- tree-outof-ssa.c	(.../trunk/gcc)	(revision 228112)
+++ tree-outof-ssa.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -315,7 +315,7 @@ insert_value_copy_on_edge (edge e, int d
   else if (src_mode == BLKmode)
     {
       x = dest_rtx;
-      store_expr (src, x, 0, false);
+      store_expr (src, x, 0, false, false);
     }
   else
     x = expand_expr (src, dest_rtx, dest_mode, EXPAND_NORMAL);
Index: gimple-expr.c
===================================================================
--- gimple-expr.c	(.../trunk/gcc)	(revision 228112)
+++ gimple-expr.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -159,14 +159,16 @@ useless_type_conversion_p (tree outer_ty
   else if (TREE_CODE (inner_type) == ARRAY_TYPE
 	   && TREE_CODE (outer_type) == ARRAY_TYPE)
     {
-      /* Preserve string attributes.  */
+      /* Preserve various attributes.  */
+      if (TYPE_REVERSE_STORAGE_ORDER (inner_type)
+	  != TYPE_REVERSE_STORAGE_ORDER (outer_type))
+	return false;
       if (TYPE_STRING_FLAG (inner_type) != TYPE_STRING_FLAG (outer_type))
 	return false;
 
       /* Conversions from array types with unknown extent to
 	 array types with known extent are not useless.  */
-      if (!TYPE_DOMAIN (inner_type)
-	  && TYPE_DOMAIN (outer_type))
+      if (!TYPE_DOMAIN (inner_type) && TYPE_DOMAIN (outer_type))
 	return false;
 
       /* Nor are conversions from array types with non-constant size to
Index: tree-core.h
===================================================================
--- tree-core.h	(.../trunk/gcc)	(revision 228112)
+++ tree-core.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1110,8 +1110,14 @@ struct GTY(()) tree_base {
 
    saturating_flag:
 
+       TYPE_REVERSE_STORAGE_ORDER in
+           RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, ARRAY_TYPE
+
        TYPE_SATURATING in
-           all types
+           other types
+
+       REF_REVERSE_STORAGE_ORDER in
+           BIT_FIELD_REF, MEM_REF
 
        VAR_DECL_IS_VIRTUAL_OPERAND in
 	   VAR_DECL
Index: lto-streamer-out.c
===================================================================
--- lto-streamer-out.c	(.../trunk/gcc)	(revision 228112)
+++ lto-streamer-out.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -977,7 +977,8 @@ hash_tree (struct streamer_tree_cache_d
     hstate.add_flag (TREE_PRIVATE (t));
   if (TYPE_P (t))
     {
-      hstate.add_flag (TYPE_SATURATING (t));
+      hstate.add_flag (AGGREGATE_TYPE_P (t)
+		       ? TYPE_REVERSE_STORAGE_ORDER (t) : TYPE_SATURATING (t));
       hstate.add_flag (TYPE_ADDR_SPACE (t));
     }
   else if (code == SSA_NAME)

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [patch 5/6] scalar-storage-order merge: rest
  2015-10-06 10:57 [patch 0/6] scalar-storage-order merge (2) Eric Botcazou
                   ` (3 preceding siblings ...)
  2015-10-06 11:05 ` [patch 4/6] scalar-storage-order merge: bulk Eric Botcazou
@ 2015-10-06 11:06 ` Eric Botcazou
  2015-10-06 11:09   ` Eric Botcazou
  2015-10-13 16:44   ` Jeff Law
  2015-10-06 11:08 ` [patch 6/6] scalar-storage-order merge: testsuite Eric Botcazou
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 32+ messages in thread
From: Eric Botcazou @ 2015-10-06 11:06 UTC (permalink / raw)
  To: gcc-patches

This is the rest of the implementation.

	* asan.c (instrument_derefs): Adjust call to get_inner_reference.
	* builtins.c (get_object_alignment_2): Likewise.
	* cfgexpand.c (expand_debug_expr): Adjust call to get_inner_reference
	and get_ref_base_and_extent.
	* dbxout.c (dbxout_expand_expr): Likewise.
	* dwarf2out.c (add_var_loc_to_decl): Likewise.
	(loc_list_for_address_of_addr_expr_of_indirect_ref): Likewise.
	(loc_list_from_tree): Likewise.
	(fortran_common): Likewise.
	* gimple-fold.c (gimple_fold_builtin_memory_op): Adjust calls to
	get_ref_base_and_extent.
	(get_base_constructor): Likewise.
	(fold_const_aggregate_ref_1): Likewise.
	* gimple-laddress.c (pass_laddress::execute): Adjust call to
	get_inner_reference.
	* gimple-ssa-strength-reduction.c (slsr_process_ref): Adjust call to
	get_inner_reference and bail out on reverse storage order.
	* ifcvt.c (noce_emit_move_insn): Adjust calls to store_bit_field.
	* ipa-cp.c (ipa_get_jf_ancestor_result): Adjust call to
	build_ref_for_offset.
	* ipa-polymorphic-call.c (set_by_invariant): Adjust call to
	get_ref_base_and_extent.
	(ipa_polymorphic_call_context): Likewise.
	(extr_type_from_vtbl_ptr_store): Likewise.
	(check_stmt_for_type_change): Likewise.
	(get_dynamic_type): Likewise.
	* ipa-prop.c (ipa_load_from_parm_agg_1): Adjust call to
	get_ref_base_and_extent.
	(compute_complex_assign_jump_func): Likewise.
	(get_ancestor_addr_info): Likewise.
	(compute_known_type_jump_func): Likewise.
	(determine_known_aggregate_parts): Likewise.
	(ipa_get_adjustment_candidate): Likewise.
	(ipa_modify_call_arguments): Set REF_REVERSE_STORAGE_ORDER on
	MEM_REF.
	* ipa-prop.h (ipa_parm_adjustment): Add REVERSE field.
	(build_ref_for_offset): Adjust prototype.
	* simplify-rtx.c (delegitimize_mem_from_attrs): Adjust call to
	get_inner_reference.
	* tree-affine.c (tree_to_aff_combination): Adjust call to
	get_inner_reference.
	(get_inner_reference_aff): Likewise.
	* tree-data-ref.c (split_constant_offset_1): Likewise.
	(dr_analyze_innermost): Likewise.  Bail out if reverse storage order.
	* tree-scalar-evolution.c (interpret_rhs_expr): Adjust call to
	get_inner_reference.
	* tree-sra.c (struct access): Add REVERSE and move WRITE around.
	(dump_access): Print new fields.
	(create_access): Adjust call to get_ref_base_and_extent and set the
	REVERSE flag according to the result.
	(completely_scalarize_record): Set the REVERSE flag.
	(scalarize_elem): Add REVERSE parameter.
	(build_access_from_expr_1): Preserve storage order barriers.
	(build_accesses_from_assign): Likewise.
	(build_ref_for_offset): Add REVERSE parameter and set the
	REF_REVERSE_STORAGE_ORDER flag accordingly.
	(build_ref_for_model): Adjust call to build_ref_for_offset and clear
	the REF_REVERSE_STORAGE_ORDER flag if there are components.
	(analyze_access_subtree): Likewise.
	(create_artificial_child_access): Set the REVERSE flag.
	(get_access_for_expr): Adjust call to get_ref_base_and_extent.
	(turn_representatives_into_adjustments): Propagate REVERSE flag.
	(ipa_sra_check_caller): Adjust call to get_inner_reference.
	* tree-ssa-alias.c (ao_ref_base): Adjust call to
	get_ref_base_and_extent.
	(aliasing_component_refs_p): Likewise.
	(stmt_kills_ref_p_1): Likewise.
	* tree-ssa-dce.c (mark_aliased_reaching_defs_necessary_1): Likewise.
	* tree-ssa-loop-ivopts.c (may_be_nonaddressable_p) <MEM_REF>: New.
	Return true if reverse storage order.
	<BIT_FIELD_REF>: Likewise.
	<COMPONENT_REF>: Likewise.
	<ARRAY_REF>: Likewise.
	<ARRAY_RANGE_REF>: Likewise.
	(split_address_cost): Likewise.  Bail out if reverse storage order.
	* tree-ssa-math-opts.c (find_bswap_or_nop_load): Adjust call to
	get_inner_reference.  Bail out if reverse storage order.
	(bswap_replace): Adjust call to get_inner_reference.
	* tree-ssa-pre.c (create_component_ref_by_pieces_1) <MEM_REF>: Set
	the REF_REVERSE_STORAGE_ORDER flag.
	<BIT_FIELD_REF>: Likewise.
	* tree-ssa-sccvn.c (vn_reference_eq): Return false on storage order
	barriers.
	(copy_reference_ops_from_ref) <MEM_REF>: Set REVERSE field according
 	to the REF_REVERSE_STORAGE_ORDER flag.
	<BIT_FIELD_REF>: Likewise.
	<VIEW_CONVERT_EXPR>: Set it for storage order barriers.
	(contains_storage_order_barrier_p): New predicate.
	(vn_reference_lookup_3): Adjust calls to get_ref_base_and_extent.
	Punt on storage order barriers if necessary.
	* tree-ssa-sccvn.h (struct vn_reference_op_struct): Add REVERSE.
	* tree-ssa-structalias.c (get_constraint_for_component_ref): Adjust
	call to get_ref_base_and_extent.
	(do_structure_copy): Likewise.
	* tree-vect-data-refs.c (vect_check_gather): Adjust call to
	get_inner_reference.
	(vect_analyze_data_refs): Likewise.  Bail out if reverse storage
	order.
	* tsan.c (instrument_expr): Adjust call to get_inner_reference.
	* ubsan.c (instrument_bool_enum_load): Likewise.
	(instrument_object_size): Likewise.
	* var-tracking.c (track_expr_p): Adjust call to
	get_ref_base_and_extent
	* config/arm/arm.c (arm_assemble_integer): Adjust call to
	assemble_real
	* config/arm/arm.md (consttable_4): Likewise.
	(consttable_8): Likewise.
	(consttable_16): Likewise.
	* config/mips/mips.md (consttable_float): Likewise.
	* config/s390/s390.c (s390_output_pool_entry): Likewise.
	* config/sh/sh.md (consttable_sf): Likewise.
	(consttable_df): Likewise.

 asan.c                          |    6 +-
 builtins.c                      |    6 +-
 cfgexpand.c                     |   12 +++--
 dbxout.c                        |    6 +-
 dwarf2out.c                     |   21 +++++-----
 gimple-fold.c                   |   13 ++++--
 gimple-laddress.c               |    4 -
 gimple-ssa-strength-reduction.c |    6 +-
 ifcvt.c                         |    4 -
 ipa-cp.c                        |    2 
 ipa-polymorphic-call.c          |   23 +++++++----
 ipa-prop.c                      |   30 ++++++++++----
 ipa-prop.h                      |    6 ++
 simplify-rtx.c                  |    7 +--
 tree-affine.c                   |   10 ++--
 tree-data-ref.c                 |   20 ++++++---
 tree-scalar-evolution.c         |    7 +--
 tree-sra.c                      |   83 +++++++++++++++++++++++---------------
 tree-ssa-alias.c                |   18 +++++---
 tree-ssa-dce.c                  |    4 +
 tree-ssa-loop-ivopts.c          |   27 +++++++++----
 tree-ssa-math-opts.c            |   10 ++--
 tree-ssa-pre.c                  |    5 +-
 tree-ssa-sccvn.c                |   61 +++++++++++++++++++++++++----
 tree-ssa-sccvn.h                |    1 
 tree-ssa-structalias.c          |   10 +++-
 tree-vect-data-refs.c           |   21 +++++++---
 tsan.c                          |    6 +-
 ubsan.c                         |    8 +--
 var-tracking.c                  |    3 -
 config/arm/arm.c                |    2 
 config/arm/arm.md               |    6 +-
 config/mips/mips.md             |    2 
 config/s390/s390.c              |    2 
 config/sh/sh.md                 |    4 -

 35 files changed, 304 insertions(+), 152 deletions(-)

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [patch 6/6] scalar-storage-order merge: testsuite
  2015-10-06 10:57 [patch 0/6] scalar-storage-order merge (2) Eric Botcazou
                   ` (4 preceding siblings ...)
  2015-10-06 11:06 ` [patch 5/6] scalar-storage-order merge: rest Eric Botcazou
@ 2015-10-06 11:08 ` Eric Botcazou
  2015-10-12 22:26   ` Jeff Law
  2015-10-09 11:33 ` [patch 0/6] scalar-storage-order merge (2) Bernd Schmidt
  2015-11-08 18:30 ` Eric Botcazou
  7 siblings, 1 reply; 32+ messages in thread
From: Eric Botcazou @ 2015-10-06 11:08 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 9125 bytes --]

This is the testsuite part.

testsuite/
	* c-c++-common/sso-1.c: New test.
	* c-c++-common/sso-2.c: Likewise.
	* c-c++-common/sso-3.c: Likewise.
	* c-c++-common/sso-4.c: Likewise.
	* c-c++-common/sso-5.c: Likewise.
	* c-c++-common/sso-6.c: Likewise.
	* c-c++-common/sso-7.c: Likewise.
        * c-c++-common/sso: New directory.
        * gcc.dg/sso-1.c: New test.
        * g++.dg/sso-1.C: Likewise.
        * gcc.dg/sso: New directory.
        * g++.dg/sso: Likewise.
	* gcc.target/i386/movbe-3.c: New test.
        * gnat.dg/sso1.adb: New test.
        * gnat.dg/sso2.ad[sb]: Likewise.
        * gnat.dg/sso3.adb: Likewise.
        * gnat.dg/sso4.adb: Likewise.
        * gnat.dg/sso5.adb: Likewise.
        * gnat.dg/sso6.adb: Likewise.
        * gnat.dg/sso7.adb: Likewise.
        * gnat.dg/specs/sso1.ads: Likewise.
        * gnat.dg/specs/sso2.ads: Likewise.
        * gnat.dg/sso: New directory.

 c-c++-common/sso-1.c      |   94 +++++++++++++++++++++++++++++++++++
 c-c++-common/sso-2.c      |   94 +++++++++++++++++++++++++++++++++++
 c-c++-common/sso-3.c      |   21 +++++++
 c-c++-common/sso-4.c      |   24 ++++++++
 c-c++-common/sso-5.c      |   72 ++++++++++++++++++++++++++
 c-c++-common/sso-6.c      |   44 ++++++++++++++++
 c-c++-common/sso-7.c      |   44 ++++++++++++++++
 c-c++-common/sso/dump.h   |   23 ++++++++
 c-c++-common/sso/init1.h  |   12 ++++
 c-c++-common/sso/init13.h |   15 +++++
 c-c++-common/sso/init2.h  |   24 ++++++++
 c-c++-common/sso/init3.h  |   34 ++++++++++++
 c-c++-common/sso/init4.h  |   14 +++++
 c-c++-common/sso/init5.h  |   14 +++++
 c-c++-common/sso/init6.h  |   24 ++++++++
 c-c++-common/sso/init7.h  |   28 ++++++++++
 c-c++-common/sso/init8.h  |   28 ++++++++++
 c-c++-common/sso/init9.h  |   14 +++++
 c-c++-common/sso/p1.c     |   64 +++++++++++++++++++++++
 c-c++-common/sso/p13.c    |   64 +++++++++++++++++++++++
 c-c++-common/sso/p2.c     |   88 ++++++++++++++++++++++++++++++++
 c-c++-common/sso/p3.c     |   88 ++++++++++++++++++++++++++++++++
 c-c++-common/sso/p4.c     |   64 +++++++++++++++++++++++
 c-c++-common/sso/p5.c     |   74 +++++++++++++++++++++++++++
 c-c++-common/sso/p6.c     |   74 +++++++++++++++++++++++++++
 c-c++-common/sso/p7.c     |   74 +++++++++++++++++++++++++++
 c-c++-common/sso/p8.c     |   74 +++++++++++++++++++++++++++
 c-c++-common/sso/p9.c     |   64 +++++++++++++++++++++++
 c-c++-common/sso/q1.c     |   50 ++++++++++++++++++
 c-c++-common/sso/q13.c    |   50 ++++++++++++++++++
 c-c++-common/sso/q2.c     |   54 ++++++++++++++++++++
 c-c++-common/sso/q3.c     |   54 ++++++++++++++++++++
 c-c++-common/sso/q4.c     |   50 ++++++++++++++++++
 c-c++-common/sso/q5.c     |   46 +++++++++++++++++
 c-c++-common/sso/q6.c     |   45 ++++++++++++++++
 c-c++-common/sso/q7.c     |   46 +++++++++++++++++
 c-c++-common/sso/q8.c     |   46 +++++++++++++++++
 c-c++-common/sso/q9.c     |   50 ++++++++++++++++++
 c-c++-common/sso/r3.c     |   65 ++++++++++++++++++++++++
 c-c++-common/sso/r5.c     |   65 ++++++++++++++++++++++++
 c-c++-common/sso/r6.c     |   65 ++++++++++++++++++++++++
 c-c++-common/sso/r7.c     |   65 ++++++++++++++++++++++++
 c-c++-common/sso/r8.c     |   65 ++++++++++++++++++++++++
 c-c++-common/sso/s3.c     |   79 +++++++++++++++++++++++++++++
 c-c++-common/sso/s5.c     |   91 ++++++++++++++++++++++++++++++++++
 c-c++-common/sso/s6.c     |   81 ++++++++++++++++++++++++++++++
 c-c++-common/sso/s7.c     |   79 +++++++++++++++++++++++++++++
 c-c++-common/sso/s8.c     |   79 +++++++++++++++++++++++++++++
 c-c++-common/sso/t1.c     |   56 ++++++++++++++++++++
 c-c++-common/sso/t13.c    |   56 ++++++++++++++++++++
 c-c++-common/sso/t2.c     |   92 ++++++++++++++++++++++++++++++++++
 c-c++-common/sso/t3.c     |   92 ++++++++++++++++++++++++++++++++++
 c-c++-common/sso/t4.c     |   56 ++++++++++++++++++++
 c-c++-common/sso/t5.c     |   72 ++++++++++++++++++++++++++
 c-c++-common/sso/t6.c     |   72 ++++++++++++++++++++++++++
 c-c++-common/sso/t7.c     |   72 ++++++++++++++++++++++++++
 c-c++-common/sso/t8.c     |   72 ++++++++++++++++++++++++++
 c-c++-common/sso/t9.c     |   56 ++++++++++++++++++++
 c-c++-common/sso/u5.c     |   52 +++++++++++++++++++
 c-c++-common/sso/u6.c     |   52 +++++++++++++++++++
 g++.dg/sso-1.C            |   17 ++++++
 g++.dg/sso/sso.exp        |   40 ++++++++++++++
 gcc.dg/sso-1.c            |   17 ++++++
 gcc.dg/sso/sso.exp        |   40 ++++++++++++++
 gcc.target/i386/movbe-3.c |   19 +++++++
 gnat.dg/specs/sso1.ads    |   22 ++++++++
 gnat.dg/specs/sso2.ads    |   26 +++++++++
 gnat.dg/sso/conv1.adb     |   50 ++++++++++++++++++
 gnat.dg/sso/dump.adb      |   17 ++++++
 gnat.dg/sso/dump.ads      |    3 +
 gnat.dg/sso/init1.ads     |   26 +++++++++
 gnat.dg/sso/init10.ads    |   23 ++++++++
 gnat.dg/sso/init11.ads    |   34 ++++++++++++
 gnat.dg/sso/init12.ads    |   25 +++++++++
 gnat.dg/sso/init13.ads    |   33 ++++++++++++
 gnat.dg/sso/init2.ads     |   69 +++++++++++++++++++++++++
 gnat.dg/sso/init3.ads     |   78 +++++++++++++++++++++++++++++
 gnat.dg/sso/init4.ads     |   27 ++++++++++
 gnat.dg/sso/init5.ads     |   39 ++++++++++++++
 gnat.dg/sso/init6.ads     |   39 ++++++++++++++
 gnat.dg/sso/init7.ads     |   59 ++++++++++++++++++++++
 gnat.dg/sso/init8.ads     |   59 ++++++++++++++++++++++
 gnat.dg/sso/init9.ads     |   27 ++++++++++
 gnat.dg/sso/p1.adb        |   62 +++++++++++++++++++++++
 gnat.dg/sso/p10.adb       |   63 +++++++++++++++++++++++
 gnat.dg/sso/p11.adb       |   68 +++++++++++++++++++++++++
 gnat.dg/sso/p12.adb       |  122 ++++++++++++++++++++++++++++++++++++++++++++
 gnat.dg/sso/p13.adb       |   63 +++++++++++++++++++++++
 gnat.dg/sso/p2.adb        |   80 +++++++++++++++++++++++++++++
 gnat.dg/sso/p3.adb        |   80 +++++++++++++++++++++++++++++
 gnat.dg/sso/p4.adb        |   63 +++++++++++++++++++++++
 gnat.dg/sso/p5.adb        |   68 +++++++++++++++++++++++++
 gnat.dg/sso/p6.adb        |   61 ++++++++++++++++++++++
 gnat.dg/sso/p7.adb        |   61 ++++++++++++++++++++++
 gnat.dg/sso/p8.adb        |   61 ++++++++++++++++++++++
 gnat.dg/sso/p9.adb        |   63 +++++++++++++++++++++++
 gnat.dg/sso/q1.adb        |   52 +++++++++++++++++++
 gnat.dg/sso/q10.adb       |   53 +++++++++++++++++++
 gnat.dg/sso/q11.adb       |   44 ++++++++++++++++
 gnat.dg/sso/q12.adb       |   43 ++++++++++++++++
 gnat.dg/sso/q13.adb       |   53 +++++++++++++++++++
 gnat.dg/sso/q2.adb        |   60 ++++++++++++++++++++++
 gnat.dg/sso/q3.adb        |   60 ++++++++++++++++++++++
 gnat.dg/sso/q4.adb        |   53 +++++++++++++++++++
 gnat.dg/sso/q5.adb        |   44 ++++++++++++++++
 gnat.dg/sso/q6.adb        |   44 ++++++++++++++++
 gnat.dg/sso/q7.adb        |   44 ++++++++++++++++
 gnat.dg/sso/q8.adb        |   44 ++++++++++++++++
 gnat.dg/sso/q9.adb        |   53 +++++++++++++++++++
 gnat.dg/sso/r11.adb       |   68 +++++++++++++++++++++++++
 gnat.dg/sso/r12.adb       |  123 ++++++++++++++++++++++++++++++++++++++++++++
 gnat.dg/sso/r3.adb        |   68 +++++++++++++++++++++++++
 gnat.dg/sso/r5.adb        |   68 +++++++++++++++++++++++++
 gnat.dg/sso/r6.adb        |   68 +++++++++++++++++++++++++
 gnat.dg/sso/r7.adb        |   68 +++++++++++++++++++++++++
 gnat.dg/sso/r8.adb        |   68 +++++++++++++++++++++++++
 gnat.dg/sso/s11.adb       |   78 +++++++++++++++++++++++++++++
 gnat.dg/sso/s12.adb       |   77 ++++++++++++++++++++++++++++
 gnat.dg/sso/s3.adb        |   79 +++++++++++++++++++++++++++++
 gnat.dg/sso/s5.adb        |   78 +++++++++++++++++++++++++++++
 gnat.dg/sso/s6.adb        |   79 +++++++++++++++++++++++++++++
 gnat.dg/sso/s7.adb        |   79 +++++++++++++++++++++++++++++
 gnat.dg/sso/s8.adb        |   79 +++++++++++++++++++++++++++++
 gnat.dg/sso/sso.exp       |   40 ++++++++++++++
 gnat.dg/sso/t1.adb        |   55 ++++++++++++++++++++
 gnat.dg/sso/t10.adb       |   56 ++++++++++++++++++++
 gnat.dg/sso/t11.adb       |   67 +++++++++++++++++++++++++
 gnat.dg/sso/t12.adb       |   66 ++++++++++++++++++++++++
 gnat.dg/sso/t13.adb       |   56 ++++++++++++++++++++
 gnat.dg/sso/t2.adb        |   84 +++++++++++++++++++++++++++++++
 gnat.dg/sso/t3.adb        |   84 +++++++++++++++++++++++++++++++
 gnat.dg/sso/t4.adb        |   56 ++++++++++++++++++++
 gnat.dg/sso/t5.adb        |   67 +++++++++++++++++++++++++
 gnat.dg/sso/t6.adb        |   67 +++++++++++++++++++++++++
 gnat.dg/sso/t7.adb        |   68 +++++++++++++++++++++++++
 gnat.dg/sso/t8.adb        |   68 +++++++++++++++++++++++++
 gnat.dg/sso/t9.adb        |   56 ++++++++++++++++++++
 gnat.dg/sso/u11.adb       |   44 ++++++++++++++++
 gnat.dg/sso/u5.adb        |   44 ++++++++++++++++
 gnat.dg/sso/u6.adb        |   44 ++++++++++++++++
 gnat.dg/sso1.adb          |   77 ++++++++++++++++++++++++++++
 gnat.dg/sso2.adb          |   14 +++++
 gnat.dg/sso2.ads          |   13 ++++
 gnat.dg/sso3.adb          |   52 +++++++++++++++++++
 gnat.dg/sso4.adb          |   55 ++++++++++++++++++++
 gnat.dg/sso5.adb          |   52 +++++++++++++++++++
 gnat.dg/sso6.adb          |   54 ++++++++++++++++++++
 gnat.dg/sso7.adb          |   52 +++++++++++++++++++
 148 files changed, 8198 insertions(+)

-- 
Eric Botcazou

[-- Attachment #2: sso-testsuite.diff --]
[-- Type: text/x-patch, Size: 237647 bytes --]

Index: testsuite/gcc.target/i386/movbe-3.c
===================================================================
--- testsuite/gcc.target/i386/movbe-3.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/gcc.target/i386/movbe-3.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mmovbe" } */
+
+struct __attribute__((scalar_storage_order("big-endian"))) S
+{
+  int i;
+};
+
+int get (struct S *s)
+{
+  return s->i;
+}
+
+void set (struct S *s, int i)
+{
+  s->i = i;
+}
+
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 2 } } */
Index: testsuite/gnat.dg/sso6.adb
===================================================================
--- testsuite/gnat.dg/sso6.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso6.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,54 @@
+-- { dg-do run }
+
+with System;
+
+procedure SSO6 is
+
+   type Short_Int is mod 2**16;
+
+   type Rec1 is record
+      F1 : Short_Int;
+      F2 : Short_Int;
+   end record;
+   for Rec1 use record
+      F1 at 0 range  0 .. 15;
+      F2 at 0 range 16 .. 31;
+   end record;
+   for Rec1'Bit_Order use System.High_Order_First;
+   for Rec1'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec2 is record
+      I1 : Integer;
+      R1 : Rec1;
+   end record;
+   for Rec2 use record
+      I1 at 0 range 0 .. 31; 
+      R1 at 4 range 0 .. 31;
+   end record;
+   for Rec2'Bit_Order use System.High_Order_First;
+   for Rec2'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec3 is record
+      Data : Rec1;
+   end record;
+   for Rec3 use record
+      Data at 0 range 1 .. 32;
+   end record;
+   for Rec3'Bit_Order use System.High_Order_First;
+   for Rec3'Scalar_Storage_Order use System.High_Order_First;
+
+   procedure Copy (Message : in Rec3) is
+      Local : Rec2;
+   begin
+      Local := (I1 => 1, R1 => Message.Data);
+      if Local.R1 /= Message.Data then
+         raise Program_Error;
+      end if;
+   end;
+
+   Message : Rec3;
+
+begin
+   Message := (Data => (2, 3));
+   Copy(Message);
+end;
Index: testsuite/gnat.dg/sso/t7.adb
===================================================================
--- testsuite/gnat.dg/sso/t7.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t7.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init7; use Init7;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T7 is
+  Verbose : constant Boolean := False;
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.N.C1 := My_R1.N.C1 + 1;
+  Local_R1.N.C2 := My_R1.N.C2 + 1;
+  Local_R1.N.C3 := My_R1.N.C3 + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.N.C1 := My_R2.N.C1 + 1;
+  Local_R2.N.C2 := My_R2.N.C2 + 1;
+  Local_R2.N.C3 := My_R2.N.C3 + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+-- 
+  Local_R1 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.N.C1 := Local_R1.N.C1 + 1;
+  Local_R1.N.C2 := Local_R1.N.C2 + 1;
+  Local_R1.N.C3 := Local_R1.N.C3 + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.N.C1 := Local_R2.N.C1 + 1;
+  Local_R2.N.C2 := Local_R2.N.C2 + 1;
+  Local_R2.N.C3 := Local_R2.N.C3 + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+end;
Index: testsuite/gnat.dg/sso/t8.adb
===================================================================
--- testsuite/gnat.dg/sso/t8.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t8.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init8; use Init8;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T8 is
+  Verbose : constant Boolean := False;
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.N.C1 := My_R1.N.C1 + 1;
+  Local_R1.N.C2 := My_R1.N.C2 + 1;
+  Local_R1.N.C3 := My_R1.N.C3 + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.N.C1 := My_R2.N.C1 + 1;
+  Local_R2.N.C2 := My_R2.N.C2 + 1;
+  Local_R2.N.C3 := My_R2.N.C3 + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.N.C1 := Local_R1.N.C1 + 1;
+  Local_R1.N.C2 := Local_R1.N.C2 + 1;
+  Local_R1.N.C3 := Local_R1.N.C3 + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.N.C1 := Local_R2.N.C1 + 1;
+  Local_R2.N.C2 := Local_R2.N.C2 + 1;
+  Local_R2.N.C3 := Local_R2.N.C3 + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+end;
Index: testsuite/gnat.dg/sso/t9.adb
===================================================================
--- testsuite/gnat.dg/sso/t9.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t9.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,56 @@
+-- { dg-do run }
+
+with Init9; use Init9;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T9 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.F := My_R1.F + 1.0;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 8c 16 22 aa fd 90 10 40\n" }
+
+  Local_R2.F := My_R2.F + 1.0;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 10 90 fd aa 22 16 8c\n" }
+
+  Local_R1.F := Pi;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Local_R2.F := Pi;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" }
+
+  Local_R1.F := Local_R1.F + 1.0;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 8c 16 22 aa fd 90 10 40\n" }
+
+  Local_R2.F := Local_R2.F + 1.0;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 10 90 fd aa 22 16 8c\n" }
+
+end;
Index: testsuite/gnat.dg/sso/q10.adb
===================================================================
--- testsuite/gnat.dg/sso/q10.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q10.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,53 @@
+-- { dg-do run }
+-- { dg-options "-gnatws" }
+
+with Init10; use Init10;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q10 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78\n" }
+
+  if A1.I /= B1.I then
+    raise Program_Error;
+  end if;
+
+  if A1.I /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/q11.adb
===================================================================
--- testsuite/gnat.dg/sso/q11.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q11.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q11 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n"} 
+
+  if A1.I /= B1.I or A1.A(1) /= B1.A(1) then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.A(1) /= B2.A(1) then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/q12.adb
===================================================================
--- testsuite/gnat.dg/sso/q12.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q12.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,43 @@
+-- { dg-do run }
+
+with Init12; use Init12;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q12 is
+
+  A1  : Arr1  := My_A1;
+  A11 : Arr11 := My_A11;
+
+  A2  : Arr2  := My_A2;
+  A22 : Arr22 := My_A22;
+
+begin
+  Put ("A1  :");
+  Dump (A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1  : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A11 :");
+  Dump (A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Put ("A2  :");
+  Dump (A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2  : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A22 :");
+  Dump (A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  if A1(1) /= A11(1,1) then
+    raise Program_Error;
+  end if;
+
+  if A2(1) /= A22(1,1) then
+    raise Program_Error;
+  end if;
+end;
Index: testsuite/gnat.dg/sso/q13.adb
===================================================================
--- testsuite/gnat.dg/sso/q13.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q13.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,53 @@
+-- { dg-do run }
+
+with Init13; use Init13;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q13 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : db 0f 49 40 db 0f 49 c0\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : db 0f 49 40 db 0f 49 c0\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 40 49 0f db c0 49 0f db\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 40 49 0f db c0 49 0f db\n" }
+
+  if A1.F /= B1.F then
+    raise Program_Error;
+  end if;
+
+  if A1.F /= (Pi, -Pi) then
+    raise Program_Error;
+  end if;
+
+  if A2.F /= B2.F then
+    raise Program_Error;
+  end if;
+
+  if A2.F /= (Pi, -Pi) then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/s11.adb
===================================================================
--- testsuite/gnat.dg/sso/s11.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/s11.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,78 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S11 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  AA1 : Arr1;
+  AA2 : Arr2;
+
+  C1 : My_Integer;
+  C2 : My_Integer;
+  C3 : My_Integer;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  AA1 := A1.A;
+  C1 := AA1(1);
+  C2 := AA1(2);
+  C3 := AA1(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA1(1) := C1;
+  AA1(2) := C2;
+  AA1(3) := C3;
+  A1.A := AA1;
+
+  AA2 := A2.A;
+  C1 := AA2(1);
+  C2 := AA2(2);
+  C3 := AA2(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA2(1) := C1;
+  AA2(2) := C2;
+  AA2(3) := C3;
+  A2.A := AA2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+end;
Index: testsuite/gnat.dg/sso/s12.adb
===================================================================
--- testsuite/gnat.dg/sso/s12.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/s12.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,77 @@
+-- { dg-do run }
+
+with Init12; use Init12;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S12 is
+
+  A11 : Arr11 := My_A11;
+  A22 : Arr22 := My_A22;
+
+  A1 : Arr1;
+  A2 : Arr2;
+
+  C1 : Integer;
+  C2 : Integer;
+  C3 : Integer;
+
+begin
+  Put ("A11 :");
+  Dump (A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Put ("A22 :");
+  Dump (A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  A1 := (A11(1,1), A11(1,2), A11(2,1));
+  C1 := A1(1);
+  C2 := A1(2);
+  C3 := A1(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 11206674\n" }
+
+  A1(1) := C1;
+  A1(2) := C2;
+  A1(3) := C3;
+  A11(1,1) := A1(1); A11(1,2) := A1(2); A11(2,1) := A1(3);
+
+  A2 := (A22(1,1), A22(1,2), A22(2,1));
+  C1 := A2(1);
+  C2 := A2(2);
+  C3 := A2(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 11206674\n" }
+
+  A2(1) := C1;
+  A2(2) := C2;
+  A2(3) := C3;
+  A22(1,1) := A2(1); A22(1,2) := A2(2); A22(2,1) := A2(3);
+
+  Put ("A11 :");
+  Dump (A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Put ("A22 :");
+  Dump (A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+end;
Index: testsuite/gnat.dg/sso/u11.adb
===================================================================
--- testsuite/gnat.dg/sso/u11.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/u11.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure U11 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+  C1 : My_Integer;
+  C2 : My_Integer;
+
+begin
+  Local_R1 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 01 00 00 00 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 00 00 00 01 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  C1 := Local_R1.A (Integer(Local_R1.I));
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Local_R1.I := Local_R1.I + 1;  
+  C1 := Local_R1.A (Integer(Local_R1.I));
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 13434932\n" }
+
+  C2 := Local_R2.A (Integer(Local_R2.I));
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 11206674\n" }
+
+  Local_R2.I := Local_R2.I + 1;  
+  C2 := Local_R2.A (Integer(Local_R2.I));
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+end;
Index: testsuite/gnat.dg/sso/q1.adb
===================================================================
--- testsuite/gnat.dg/sso/q1.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q1.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,52 @@
+-- { dg-do run }
+
+with Init1; use Init1;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q1 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78\n" }
+
+  if A1.I /= B1.I then
+    raise Program_Error;
+  end if;
+
+  if A1.I /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/q2.adb
===================================================================
--- testsuite/gnat.dg/sso/q2.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q2.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,60 @@
+-- { dg-do run }
+
+with Init2; use Init2;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q2 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  if A1.S1 /= B1.S1 then
+    raise Program_Error;
+  end if;
+
+  if A1.S1 /= 2 then
+    raise Program_Error;
+  end if;
+
+  if A2.S1 /= B2.S1 then
+    raise Program_Error;
+  end if;
+
+  if A2.S1 /= 2 then
+    raise Program_Error;
+  end if;
+
+  if A1.I /= B1.I or A1.A(1) /= B1.A(1) then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.A(1) /= B2.A(1) then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/q3.adb
===================================================================
--- testsuite/gnat.dg/sso/q3.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q3.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,60 @@
+-- { dg-do run }
+
+with Init3; use Init3;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q3 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  if A1.S1 /= B1.S1 then
+    raise Program_Error;
+  end if;
+
+  if A1.S1 /= 2 then
+    raise Program_Error;
+  end if;
+
+  if A2.S1 /= B2.S1 then
+    raise Program_Error;
+  end if;
+
+  if A2.S1 /= 2 then
+    raise Program_Error;
+  end if;
+
+  if A1.I /= B1.I or A1.N.C1 /= B1.N.C1 then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.N.C1 /= B2.N.C1 then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/q4.adb
===================================================================
--- testsuite/gnat.dg/sso/q4.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q4.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,53 @@
+-- { dg-do run }
+
+with Init4; use Init4;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q4 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : db 0f 49 40\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : db 0f 49 40\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 40 49 0f db\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 40 49 0f db\n" }
+
+  if A1.F /= B1.F then
+    raise Program_Error;
+  end if;
+
+  if A1.F /= Pi then
+    raise Program_Error;
+  end if;
+
+  if A2.F /= B2.F then
+    raise Program_Error;
+  end if;
+
+  if A2.F /= Pi then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/init10.ads
===================================================================
--- testsuite/gnat.dg/sso/init10.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init10.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,23 @@
+with System;
+
+package Init10 is
+
+  type My_Integer is new Integer;
+  for My_Integer'Alignment use 1;
+
+  type R1 is record
+    I : My_Integer;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R2 is record
+    I : My_Integer;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+
+  My_R1 : constant R1 := (I => 16#12345678#);
+  My_R2 : constant R2 := (I => 16#12345678#);
+
+end Init10;
Index: testsuite/gnat.dg/sso/q5.adb
===================================================================
--- testsuite/gnat.dg/sso/q5.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q5.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q5 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n"} 
+
+  if A1.I /= B1.I or A1.A(1) /= B1.A(1) then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.A(1) /= B2.A(1) then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/q6.adb
===================================================================
--- testsuite/gnat.dg/sso/q6.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q6.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q6 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  if A1.I /= B1.I or A1.A(1) /= B1.A(1) then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.A(1) /= B2.A(1) then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/init11.ads
===================================================================
--- testsuite/gnat.dg/sso/init11.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init11.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,34 @@
+with System;
+
+package Init11 is
+
+  type My_Integer is new Integer;
+  for My_Integer'Alignment use 1;
+
+  type Arr1 is array (1 .. 3) of My_Integer;
+  for Arr1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R1 is record
+    I : My_Integer;
+    A : Arr1;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type Arr2 is array (1 .. 3) of My_Integer;
+  for Arr2'Scalar_Storage_Order use System.High_Order_First;
+
+  type R2 is record
+    I : My_Integer;
+    A : Arr2;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+
+  My_R1 : constant R1 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+  My_R2 : constant R2 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+end Init11;
Index: testsuite/gnat.dg/sso/conv1.adb
===================================================================
--- testsuite/gnat.dg/sso/conv1.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/conv1.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,50 @@
+-- { dg-do run }
+
+with System; use System;
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure Conv1 is
+   type Short is mod 2**16;
+
+   type R_L is record
+      S : Short;
+      C : Character;
+   end record;
+   for R_L'Bit_Order use Low_Order_First;
+   for R_L'Scalar_Storage_Order use Low_Order_First;
+   for R_L use record
+      S at 0 range 0 .. 15;
+      C at 2 range 0 .. 7;
+   end record;
+
+   type R_H is new R_L;
+   for R_H'Bit_Order use High_Order_First;
+   for R_H'Scalar_Storage_Order use High_Order_First;
+   for R_H use record
+      S at 0 range 0 .. 15;
+      C at 2 range 0 .. 7;
+   end record;
+
+   procedure Dump (Name : String; S : Short; C : Character) is
+   begin
+      Put_Line (Name & " = (S =>" & S'Img & ", C => '" & C & "')");
+   end Dump;
+
+   X_L : R_L;
+   X_H : R_H;
+begin
+   X_L.S := 12345;
+   X_L.C := 'a';
+   Dump ("X_L", X_L.S, X_L.C);
+   -- { dg-output "X_L = \\(S => 12345, C => 'a'\\)\n" }
+
+   X_H.S := 23456;
+   X_H.C := 'b';
+   Dump ("X_H", X_H.S, X_H.C);
+   -- { dg-output "X_H = \\(S => 23456, C => 'b'\\)\n" }
+
+   X_H := R_H (X_L);
+   Dump ("X_H", X_H.S, X_H.C);
+   -- { dg-output "X_H = \\(S => 12345, C => 'a'\\)\n" }
+
+end;
Index: testsuite/gnat.dg/sso/q7.adb
===================================================================
--- testsuite/gnat.dg/sso/q7.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q7.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init7; use Init7;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q7 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  if A1.I /= B1.I or A1.N.C1 /= B1.N.C1 then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.N.C1 /= B2.N.C1 then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/init12.ads
===================================================================
--- testsuite/gnat.dg/sso/init12.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init12.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,25 @@
+with System;
+
+package Init12 is
+
+  type Arr1 is array (1 .. 3) of Integer;
+  for Arr1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type Arr11 is array (1 .. 2, 1 .. 2) of Integer;
+  for Arr11'Scalar_Storage_Order use System.Low_Order_First;
+
+  type Arr2 is array (1 .. 3) of Integer;
+  for Arr2'Scalar_Storage_Order use System.High_Order_First;
+
+  type Arr22 is array (1 .. 2, 1 .. 2) of Integer;
+  for Arr22'Scalar_Storage_Order use System.High_Order_First;
+
+  My_A1   : constant Arr1   := (16#AB0012#, 16#CD0034#, 16#EF0056#);
+  My_A11  : constant Arr11  := (1 => (16#AB0012#, 16#CD0034#),
+                                2 => (16#AB0012#, 16#CD0034#));
+
+  My_A2   : constant Arr2   := (16#AB0012#, 16#CD0034#, 16#EF0056#);
+  My_A22  : constant Arr22  := (1 => (16#AB0012#, 16#CD0034#),
+                                2 => (16#AB0012#, 16#CD0034#));
+
+end Init12;
Index: testsuite/gnat.dg/sso/q8.adb
===================================================================
--- testsuite/gnat.dg/sso/q8.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q8.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init8; use Init8;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q8 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  if A1.I /= B1.I or A1.N.C1 /= B1.N.C1 then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.N.C1 /= B2.N.C1 then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/init13.ads
===================================================================
--- testsuite/gnat.dg/sso/init13.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init13.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,33 @@
+with Ada.Numerics; use Ada.Numerics;
+with System;
+
+package Init13 is
+
+  type Complex is record
+    R : Float;
+    I : Float;
+  end record;
+  pragma Complex_Representation (Complex);
+
+  type R1 is record
+    F : Complex;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    F at 0 range 0 .. 63;
+  end record;
+
+  type R2 is record
+    F : Complex;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    F at 0 range 0 .. 63;
+  end record;
+
+  My_R1 : constant R1 := (F => (Pi, -Pi));
+  My_R2 : constant R2 := (F => (Pi, -Pi));
+
+end Init13;
Index: testsuite/gnat.dg/sso/q9.adb
===================================================================
--- testsuite/gnat.dg/sso/q9.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/q9.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,53 @@
+-- { dg-do run }
+
+with Init9; use Init9;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q9 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 40 09 21 fb 54 44 2d 18\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 40 09 21 fb 54 44 2d 18\n" }
+
+  if A1.F /= B1.F then
+    raise Program_Error;
+  end if;
+
+  if A1.F /= Pi then
+    raise Program_Error;
+  end if;
+
+  if A2.F /= B2.F then
+    raise Program_Error;
+  end if;
+
+  if A2.F /= Pi then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/u5.adb
===================================================================
--- testsuite/gnat.dg/sso/u5.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/u5.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure U5 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+  C1 : Integer;
+  C2 : Integer;
+
+begin
+  Local_R1 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 01 00 00 00 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 00 00 00 01 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  C1 := Local_R1.A (Local_R1.I);
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Local_R1.I := Local_R1.I + 1;  
+  C1 := Local_R1.A (Local_R1.I);
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 13434932\n" }
+
+  C2 := Local_R2.A (Local_R2.I);
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 11206674\n" }
+
+  Local_R2.I := Local_R2.I + 1;  
+  C2 := Local_R2.A (Local_R2.I);
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+end;
Index: testsuite/gnat.dg/sso/u6.adb
===================================================================
--- testsuite/gnat.dg/sso/u6.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/u6.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure U6 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+  C1 : Integer;
+  C2 : Integer;
+
+begin
+  Local_R1 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 01 00 00 00 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R2 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 00 00 00 01 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  C1 := Local_R1.A (Local_R1.I);
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Local_R1.I := Local_R1.I + 1;  
+  C1 := Local_R1.A (Local_R1.I);
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 13434932\n" }
+
+  C2 := Local_R2.A (Local_R2.I);
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 11206674\n" }
+
+  Local_R2.I := Local_R2.I + 1;  
+  C2 := Local_R2.A (Local_R2.I);
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+end;
Index: testsuite/gnat.dg/sso/r3.adb
===================================================================
--- testsuite/gnat.dg/sso/r3.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/r3.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init3; use Init3;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R3 is
+
+  function Get_Elem (R : R1) return Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.I;
+  end;
+
+  procedure Set_Elem (R : access R1; I : Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.I := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.I;
+  end;
+
+  procedure Set_Elem (R : access R2; I : Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.I := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  --  { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  if Get_Elem (A1) /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/r5.adb
===================================================================
--- testsuite/gnat.dg/sso/r5.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/r5.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R5 is
+
+  function Get_Elem (R : R1) return Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R1; I : Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R2; I : Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/r6.adb
===================================================================
--- testsuite/gnat.dg/sso/r6.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/r6.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R6 is
+
+  function Get_Elem (R : R1) return Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R1; I : Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R2; I : Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/r7.adb
===================================================================
--- testsuite/gnat.dg/sso/r7.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/r7.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init7; use Init7;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R7 is
+
+  function Get_Elem (R : R1) return Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.N.C1;
+  end;
+
+  procedure Set_Elem (R : access R1; I : Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.N.C1 := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.N.C1;
+  end;
+
+  procedure Set_Elem (R : access R2; I : Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.N.C1 := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/r8.adb
===================================================================
--- testsuite/gnat.dg/sso/r8.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/r8.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init8; use Init8;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R8 is
+
+  function Get_Elem (R : R1) return Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.N.C1;
+  end;
+
+  procedure Set_Elem (R : access R1; I : Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.N.C1 := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.N.C1;
+  end;
+
+  procedure Set_Elem (R : access R2; I : Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.N.C1 := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/p10.adb
===================================================================
--- testsuite/gnat.dg/sso/p10.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p10.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,63 @@
+-- { dg-do run }
+-- { dg-options "-gnatws" }
+
+with Init10; use Init10;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P10 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := 16#12345678#;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := 16#12345678#;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := Local_R2.I;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := Local_R1.I;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+end;
Index: testsuite/gnat.dg/sso/p11.adb
===================================================================
--- testsuite/gnat.dg/sso/p11.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p11.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P11 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1.I    := Local_R2.I;
+  Local_R1.A(1) := Local_R2.A(1);
+  Local_R1.A(2) := Local_R2.A(2);
+  Local_R1.A(3) := Local_R2.A(3);
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2.I    := Local_R1.I;
+  Local_R2.A(1) := Local_R1.A(1);
+  Local_R2.A(2) := Local_R1.A(2);
+  Local_R2.A(3) := Local_R1.A(3);
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+end;
Index: testsuite/gnat.dg/sso/p12.adb
===================================================================
--- testsuite/gnat.dg/sso/p12.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p12.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,122 @@
+-- { dg-do run }
+
+with Init12; use Init12;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P12 is
+
+  Local_A1  : Arr1;
+  Local_A11 : Arr11;
+  Local_A2  : Arr2;
+  Local_A22 : Arr22;
+
+begin
+  Put ("My_A1     :");
+  Dump (My_A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_A1     : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("My_A11    :");
+  Dump (My_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_A11    : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Put ("My_A2     :");
+  Dump (My_A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_A2     : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("My_A22    :");
+  Dump (My_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_A22    : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  Local_A1 := My_A1;
+  Put ("Local_A1  :");
+  Dump (Local_A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A1  : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_A11 := My_A11;
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Local_A2 := My_A2;
+  Put ("Local_A2  :");
+  Dump (Local_A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A2  : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_A22 := My_A22;
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  Local_A1 := (16#AB0012#, 16#CD0034#, 16#EF0056#);
+  Put ("Local_A1  :");
+  Dump (Local_A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A1  : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_A11 := (1 => (16#AB0012#, 16#CD0034#),
+                2 => (16#AB0012#, 16#CD0034#));
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Local_A2 := (16#AB0012#, 16#CD0034#, 16#EF0056#);
+  Put ("Local_A2  :");
+  Dump (Local_A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A2  : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_A22 := (1 => (16#AB0012#, 16#CD0034#),
+                2 => (16#AB0012#, 16#CD0034#));
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  Local_A1(1) := Local_A2(1);
+  Local_A1(2) := Local_A2(2);
+  Local_A1(3) := Local_A2(3);
+
+  Put ("Local_A1  :");
+  Dump (Local_A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A1  : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_A11(1,1) := Local_A22(1,1);
+  Local_A11(1,2) := Local_A22(1,2);
+  Local_A11(2,1) := Local_A22(2,1);
+  Local_A11(2,2) := Local_A22(2,2);
+
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Local_A2(1) := Local_A1(1);
+  Local_A2(2) := Local_A1(2);
+  Local_A2(3) := Local_A1(3);
+
+  Put ("Local_A2  :");
+  Dump (Local_A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A2  : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_A22(1,1) := Local_A11(1,1);
+  Local_A22(1,2) := Local_A11(1,2);
+  Local_A22(2,1) := Local_A11(2,1);
+  Local_A22(2,2) := Local_A11(2,2);
+
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+end;
Index: testsuite/gnat.dg/sso/p13.adb
===================================================================
--- testsuite/gnat.dg/sso/p13.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p13.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,63 @@
+-- { dg-do run }
+
+with Init13; use Init13;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P13 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : db 0f 49 40 db 0f 49 c0\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 40 49 0f db c0 49 0f db\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40 db 0f 49 c0\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db c0 49 0f db\n" }
+
+  Local_R1.F := (Pi, -Pi);
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40 db 0f 49 c0\n" }
+
+  Local_R2.F := (Pi, -Pi);
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db c0 49 0f db\n" }
+
+  Local_R1.F := Local_R2.F;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40 db 0f 49 c0\n" }
+
+  Local_R2.F := Local_R1.F;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db c0 49 0f db\n" }
+end;
Index: testsuite/gnat.dg/sso/r11.adb
===================================================================
--- testsuite/gnat.dg/sso/r11.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/r11.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R11 is
+
+  function Get_Elem (R : R1) return My_Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R1; I : My_Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return My_Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R2; I : My_Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: testsuite/gnat.dg/sso/r12.adb
===================================================================
--- testsuite/gnat.dg/sso/r12.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/r12.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,123 @@
+-- { dg-do run }
+
+with Init12; use Init12;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R12 is
+
+  function Get_Elem (A : Arr1) return Integer is
+    Tmp : Arr1 := A;
+  begin
+    return Tmp(1);
+  end;
+
+  procedure Set_Elem (A : access Arr1; I : Integer) is
+    Tmp : Arr1 := A.all;
+  begin
+    Tmp(1) := I;
+    A.all := Tmp;
+  end;
+
+  function Get_Elem (A : Arr11) return Integer is
+    Tmp : Arr11 := A;
+  begin
+    return Tmp(1,1);
+  end;
+
+  procedure Set_Elem (A : access Arr11; I : Integer) is
+    Tmp : Arr11 := A.all;
+  begin
+    Tmp(1,1) := I;
+    A.all := Tmp;
+  end;
+
+  function Get_Elem (A : Arr2) return Integer is
+    Tmp : Arr2 := A;
+  begin
+    return Tmp(1);
+  end;
+
+  procedure Set_Elem (A : access Arr2; I : Integer) is
+    Tmp : Arr2 := A.all;
+  begin
+    Tmp(1) := I;
+    A.all := Tmp;
+  end;
+
+  function Get_Elem (A : Arr22) return Integer is
+    Tmp : Arr22 := A;
+  begin
+    return Tmp(1,1);
+  end;
+
+  procedure Set_Elem (A : access Arr22; I : Integer) is
+    Tmp : Arr22 := A.all;
+  begin
+    Tmp(1,1) := I;
+    A.all := Tmp;
+  end;
+
+  A1  : aliased Arr1  := My_A1;
+  A11 : aliased Arr11 := My_A11;
+
+  A2  : aliased Arr2  := My_A2;
+  A22 : aliased Arr22 := My_A22;
+
+begin
+  Put ("A1  :");
+  Dump (A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1  : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A11 :");
+  Dump (A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Put ("A2  :");
+  Dump (A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2  : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A22 :");
+  Dump (A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A11) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A11'Access, 16#CD0034#);
+  if Get_Elem (A11) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A22) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A22'Access, 16#CD0034#);
+  if Get_Elem (A22) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+end;
Index: testsuite/gnat.dg/sso/t10.adb
===================================================================
--- testsuite/gnat.dg/sso/t10.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t10.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,56 @@
+-- { dg-do run }
+-- { dg-options "-gnatws" }
+
+with Init10; use Init10;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T10 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I := My_R1.I + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12\n" }
+
+  Local_R2.I := My_R2.I + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79\n" }
+
+  Local_R1.I := 16#12345678#;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := 16#12345678#;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := Local_R1.I + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12\n" }
+
+  Local_R2.I := Local_R2.I + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79\n" }
+
+end;
Index: testsuite/gnat.dg/sso/init1.ads
===================================================================
--- testsuite/gnat.dg/sso/init1.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init1.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,26 @@
+with System;
+
+package Init1 is
+
+  type R1 is record
+    I : Integer;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    I at 0 range 0 .. 31;
+  end record;
+
+  type R2 is record
+    I : Integer;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    I at 0 range 0 .. 31;
+  end record;
+
+  My_R1 : constant R1 := (I => 16#12345678#);
+  My_R2 : constant R2 := (I => 16#12345678#);
+
+end Init1;
Index: testsuite/gnat.dg/sso/t11.adb
===================================================================
--- testsuite/gnat.dg/sso/t11.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t11.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,67 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T11 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.A(1) := My_R1.A(1) + 1;
+  Local_R1.A(2) := My_R1.A(2) + 1;
+  Local_R1.A(3) := My_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.A(1) := My_R2.A(1) + 1;
+  Local_R2.A(2) := My_R2.A(2) + 1;
+  Local_R2.A(3) := My_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.A(1) := Local_R1.A(1) + 1;
+  Local_R1.A(2) := Local_R1.A(2) + 1;
+  Local_R1.A(3) := Local_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.A(1) := Local_R2.A(1) + 1;
+  Local_R2.A(2) := Local_R2.A(2) + 1;
+  Local_R2.A(3) := Local_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+end;
Index: testsuite/gnat.dg/sso/init2.ads
===================================================================
--- testsuite/gnat.dg/sso/init2.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init2.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,69 @@
+with System;
+
+package Init2 is
+
+  type Small is mod 2**2;
+  for Small'Size use 2;
+
+  type Count is mod 2**9;
+  for Count'Size use 9;
+
+  type Arr1 is array (1 .. 3) of Count;
+  pragma Pack (Arr1);
+  for Arr1'Size use 27;
+  for Arr1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R1 is record
+    S1 : Small;
+    I  : Integer;
+    S2 : Small;
+    A  : Arr1;
+    B  : Boolean;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    S1 at 0 range  0 ..  1;
+    I  at 0 range  2 .. 33;
+    S2 at 0 range 34 .. 35;
+    A  at 0 range 36 .. 62;
+    B  at 0 range 63 .. 63;
+  end record;
+  for R1'Size use 64;
+
+  type Arr2 is array (1 .. 3) of Count;
+  pragma Pack (Arr2);
+  for Arr2'Size use 27;
+  for Arr2'Scalar_Storage_Order use System.High_Order_First;
+
+  type R2 is record
+    S1 : Small;
+    I  : Integer;
+    S2 : Small;
+    A  : Arr2;
+    B  : Boolean;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    S1 at 0 range  0 ..  1;
+    I  at 0 range  2 .. 33;
+    S2 at 0 range 34 .. 35;
+    A  at 0 range 36 .. 62;
+    B  at 0 range 63 .. 63;
+  end record;
+  for R2'Size use 64;
+
+  My_R1 : constant R1 := (S1 => 2,
+                          I  => 16#12345678#,
+                          S2 => 1,
+                          A  => (16#AB#, 16#CD#, 16#EF#),
+                          B  => True);
+
+  My_R2 : constant R2 := (S1 => 2,
+                          I  => 16#12345678#,
+                          S2 => 1,
+                          A  => (16#AB#, 16#CD#, 16#EF#),
+                          B  => True);
+
+end Init2;
Index: testsuite/gnat.dg/sso/t12.adb
===================================================================
--- testsuite/gnat.dg/sso/t12.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t12.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,66 @@
+-- { dg-do run }
+-- 
+with Init12; use Init12;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T12 is
+
+  Local_A11 : Arr11;
+  Local_A22 : Arr22;
+
+begin
+  Local_A11(1,1) := My_A11(1,1) + 1;
+  Local_A11(1,2) := My_A11(1,2) + 1;
+  Local_A11(2,1) := My_A11(2,1) + 1;
+  Local_A11(2,2) := My_A11(2,2) + 1;
+
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 13 00 ab 00 35 00 cd 00 13 00 ab 00 35 00 cd 00\n" }
+
+  Local_A22(1,1) := My_A22(1,1) + 1;
+  Local_A22(1,2) := My_A22(1,2) + 1;
+  Local_A22(2,1) := My_A22(2,1) + 1;
+  Local_A22(2,2) := My_A22(2,2) + 1;
+
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 13 00 cd 00 35 00 ab 00 13 00 cd 00 35\n" }
+
+  Local_A11 := (1 => (16#AB0012#, 16#CD0034#),
+                2 => (16#AB0012#, 16#CD0034#));
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\\n" }
+
+  Local_A22 := (1 => (16#AB0012#, 16#CD0034#),
+                2 => (16#AB0012#, 16#CD0034#));
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  Local_A11(1,1) := Local_A11(1,1) + 1;
+  Local_A11(1,2) := Local_A11(1,2) + 1;
+  Local_A11(2,1) := Local_A11(2,1) + 1;
+  Local_A11(2,2) := Local_A11(2,2) + 1;
+
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 13 00 ab 00 35 00 cd 00 13 00 ab 00 35 00 cd 00\n" }
+
+  Local_A22(1,1) := Local_A22(1,1) + 1;
+  Local_A22(1,2) := Local_A22(1,2) + 1;
+  Local_A22(2,1) := Local_A22(2,1) + 1;
+  Local_A22(2,2) := Local_A22(2,2) + 1;
+
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 13 00 cd 00 35 00 ab 00 13 00 cd 00 35\n" }
+end;
Index: testsuite/gnat.dg/sso/init3.ads
===================================================================
--- testsuite/gnat.dg/sso/init3.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init3.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,78 @@
+with System;
+
+package Init3 is
+
+  type Small is mod 2**2;
+  for Small'Size use 2;
+
+  type Count is mod 2**9;
+  for Count'Size use 9;
+
+  type Nested1 is record
+    C1 : Count;
+    C2 : Count;
+    C3 : Count;
+  end record;
+  pragma Pack (Nested1);
+  for Nested1'Size use 27;
+  for Nested1'Bit_Order use System.Low_Order_First;
+  for Nested1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R1 is record
+    S1 : Small;
+    I  : Integer;
+    S2 : Small;
+    N  : Nested1;
+    B  : Boolean;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    S1 at 0 range  0 ..  1;
+    I  at 0 range  2 .. 33;
+    S2 at 0 range 34 .. 35;
+    N  at 0 range 36 .. 62;
+    B  at 0 range 63 .. 63;
+  end record;
+  for R1'Size use 64;
+
+  type Nested2 is record
+    C1 : Count;
+    C2 : Count;
+    C3 : Count;
+  end record;
+  pragma Pack (Nested2);
+  for Nested2'Size use 27;
+  for Nested2'Bit_Order use System.High_Order_First;
+  for Nested2'Scalar_Storage_Order use System.High_Order_First;
+  type R2 is record
+    S1 : Small;
+    I  : Integer;
+    S2 : Small;
+    N  : Nested2;
+    B  : Boolean;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    S1 at 0 range  0 ..  1;
+    I  at 0 range  2 .. 33;
+    S2 at 0 range 34 .. 35;
+    N  at 0 range 36 .. 62;
+    B  at 0 range 63 .. 63;
+  end record;
+  for R2'Size use 64;
+
+  My_R1 : constant R1 := (S1 => 2,
+                          I  => 16#12345678#,
+                          S2 => 1,
+                          N  => (16#AB#, 16#CD#, 16#EF#),
+                          B  => True);
+
+  My_R2 : constant R2 := (S1 => 2,
+                          I  => 16#12345678#,
+                          S2 => 1,
+                          N  => (16#AB#, 16#CD#, 16#EF#),
+                          B  => True);
+
+end Init3;
Index: testsuite/gnat.dg/sso/t13.adb
===================================================================
--- testsuite/gnat.dg/sso/t13.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t13.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,56 @@
+-- { dg-do run }
+
+with Init13; use Init13;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T13 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.F := (My_R1.F.R + 1.0, My_R1.F.I + 1.0);
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : ee 87 84 40 db 0f 09 c0\n" }
+
+  Local_R2.F := (My_R2.F.R + 1.0, My_R2.F.I + 1.0);
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 84 87 ee c0 09 0f db\n" }
+
+  Local_R1.F := (Pi, -Pi);
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40 db 0f 49 c0\n" }
+
+  Local_R2.F := (Pi, -Pi);
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db c0 49 0f db\n" }
+
+  Local_R1.F := (Local_R1.F.R + 1.0, Local_R1.F.I + 1.0);
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : ee 87 84 40 db 0f 09 c0\n" }
+
+  Local_R2.F := (Local_R2.F.R + 1.0, Local_R2.F.I + 1.0);
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 84 87 ee c0 09 0f db\n" }
+
+end;
Index: testsuite/gnat.dg/sso/init4.ads
===================================================================
--- testsuite/gnat.dg/sso/init4.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init4.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,27 @@
+with Ada.Numerics; use Ada.Numerics;
+with System;
+
+package Init4 is
+
+  type R1 is record
+    F : Float;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    F at 0 range 0 .. 31;
+  end record;
+
+  type R2 is record
+    F : Float;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    F at 0 range 0 .. 31;
+  end record;
+
+  My_R1 : constant R1 := (F => Pi);
+  My_R2 : constant R2 := (F => Pi);
+
+end Init4;
Index: testsuite/gnat.dg/sso/init5.ads
===================================================================
--- testsuite/gnat.dg/sso/init5.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init5.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,39 @@
+with System;
+
+package Init5 is
+
+  type Arr1 is array (1 .. 3) of Integer;
+  for Arr1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R1 is record
+    I : Integer;
+    A : Arr1;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    I at 0 range 0 .. 31;
+    A at 4 range 0 .. 95;
+  end record;
+
+  type Arr2 is array (1 .. 3) of Integer;
+  for Arr2'Scalar_Storage_Order use System.High_Order_First;
+
+  type R2 is record
+    I : Integer;
+    A : Arr2;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    I at 0 range 0 .. 31;
+    A at 4 range 0 .. 95;
+  end record;
+
+  My_R1 : constant R1 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+  My_R2 : constant R2 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+end Init5;
Index: testsuite/gnat.dg/sso/init6.ads
===================================================================
--- testsuite/gnat.dg/sso/init6.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init6.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,39 @@
+with System;
+
+package Init6 is
+
+  type Arr1 is array (1 .. 3) of Integer;
+  for Arr1'Scalar_Storage_Order use System.High_Order_First;
+
+  type R1 is record
+    I : Integer;
+    A : Arr1;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    I at 0 range 0 .. 31;
+    A at 4 range 0 .. 95;
+  end record;
+
+  type Arr2 is array (1 .. 3) of Integer;
+  for Arr2'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R2 is record
+    I : Integer;
+    A : Arr2;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    I at 0 range 0 .. 31;
+    A at 4 range 0 .. 95;
+  end record;
+
+  My_R1 : constant R1 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+  My_R2 : constant R2 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+end Init6;
Index: testsuite/gnat.dg/sso/init7.ads
===================================================================
--- testsuite/gnat.dg/sso/init7.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init7.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,59 @@
+with System;
+
+package Init7 is
+
+  type Nested1 is record
+    C1 : Integer;
+    C2 : Integer;
+    C3 : Integer;
+  end record;
+  for Nested1'Bit_Order use System.Low_Order_First;
+  for Nested1'Scalar_Storage_Order use System.Low_Order_First;
+  for Nested1 use record
+    C1 at 0 range 0 .. 31;
+    C2 at 4 range 0 .. 31;
+    C3 at 8 range 0 .. 31;
+  end record;
+
+  type R1 is record
+    I : Integer;
+    N : Nested1;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    I at 0 range 0 .. 31;
+    N at 4 range 0 .. 95;
+  end record;
+
+  type Nested2 is record
+    C1 : Integer;
+    C2 : Integer;
+    C3 : Integer;
+  end record;
+  for Nested2'Bit_Order use System.High_Order_First;
+  for Nested2'Scalar_Storage_Order use System.High_Order_First;
+  for Nested2 use record
+    C1 at 0 range 0 .. 31;
+    C2 at 4 range 0 .. 31;
+    C3 at 8 range 0 .. 31;
+  end record;
+
+  type R2 is record
+    I : Integer;
+    N : Nested2;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    I at 0 range 0 .. 31;
+    N at 4 range 0 .. 95;
+  end record;
+
+  My_R1 : constant R1 := (I => 16#12345678#,
+                          N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+  My_R2 : constant R2 := (I => 16#12345678#,
+                          N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+end Init7;
Index: testsuite/gnat.dg/sso/init8.ads
===================================================================
--- testsuite/gnat.dg/sso/init8.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init8.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,59 @@
+with System;
+
+package Init8 is
+
+  type Nested1 is record
+    C1 : Integer;
+    C2 : Integer;
+    C3 : Integer;
+  end record;
+  for Nested1'Bit_Order use System.High_Order_First;
+  for Nested1'Scalar_Storage_Order use System.High_Order_First;
+  for Nested1 use record
+    C1 at 0 range 0 .. 31;
+    C2 at 4 range 0 .. 31;
+    C3 at 8 range 0 .. 31;
+  end record;
+
+  type R1 is record
+    I : Integer;
+    N : Nested1;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    I at 0 range 0 .. 31;
+    N at 4 range 0 .. 95;
+  end record;
+
+  type Nested2 is record
+    C1 : Integer;
+    C2 : Integer;
+    C3 : Integer;
+  end record;
+  for Nested2'Bit_Order use System.Low_Order_First;
+  for Nested2'Scalar_Storage_Order use System.Low_Order_First;
+  for Nested2 use record
+    C1 at 0 range 0 .. 31;
+    C2 at 4 range 0 .. 31;
+    C3 at 8 range 0 .. 31;
+  end record;
+
+  type R2 is record
+    I : Integer;
+    N : Nested2;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    I at 0 range 0 .. 31;
+    N at 4 range 0 .. 95;
+  end record;
+
+  My_R1 : constant R1 := (I => 16#12345678#,
+                          N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+  My_R2 : constant R2 := (I => 16#12345678#,
+                          N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+end Init8;
Index: testsuite/gnat.dg/sso/init9.ads
===================================================================
--- testsuite/gnat.dg/sso/init9.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/init9.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,27 @@
+with Ada.Numerics; use Ada.Numerics;
+with System;
+
+package Init9 is
+
+  type R1 is record
+    F : Long_Float;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    F at 0 range 0 .. 63;
+  end record;
+
+  type R2 is record
+    F : Long_Float;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    F at 0 range 0 .. 63;
+  end record;
+
+  My_R1 : constant R1 := (F => Pi);
+  My_R2 : constant R2 := (F => Pi);
+
+end Init9;
Index: testsuite/gnat.dg/sso/s3.adb
===================================================================
--- testsuite/gnat.dg/sso/s3.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/s3.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,79 @@
+-- { dg-do run }
+
+with Init3; use Init3;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S3 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  N1 : Nested1;
+  N2 : Nested2;
+
+  C1 : Init3.Count;
+  C2 : Init3.Count;
+  C3 : Init3.Count;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  N1 := A1.N;
+  C1 := N1.C1;
+  C2 := N1.C2;
+  C3 := N1.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 171\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 205\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 239\n" }
+
+  N1.C1 := C1;
+  N1.C2 := C2;
+  N1.C3 := C3;
+  A1.N := N1;
+
+  N2 := A2.N;
+  C1 := N2.C1;
+  C2 := N2.C2;
+  C3 := N2.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 171\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 205\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 239\n" }
+
+  N2.C1 := C1;
+  N2.C2 := C2;
+  N2.C3 := C3;
+  A2.N := N2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+end;
Index: testsuite/gnat.dg/sso/s5.adb
===================================================================
--- testsuite/gnat.dg/sso/s5.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/s5.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,78 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S5 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  AA1 : Arr1;
+  AA2 : Arr2;
+
+  C1 : Integer;
+  C2 : Integer;
+  C3 : Integer;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  AA1 := A1.A;
+  C1 := AA1(1);
+  C2 := AA1(2);
+  C3 := AA1(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA1(1) := C1;
+  AA1(2) := C2;
+  AA1(3) := C3;
+  A1.A := AA1;
+
+  AA2 := A2.A;
+  C1 := AA2(1);
+  C2 := AA2(2);
+  C3 := AA2(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA2(1) := C1;
+  AA2(2) := C2;
+  AA2(3) := C3;
+  A2.A := AA2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+end;
Index: testsuite/gnat.dg/sso/s6.adb
===================================================================
--- testsuite/gnat.dg/sso/s6.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/s6.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,79 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S6 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  AA1 : Arr1;
+  AA2 : Arr2;
+
+  C1 : Integer;
+  C2 : Integer;
+  C3 : Integer;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  AA1 := A1.A;
+  C1 := AA1(1);
+  C2 := AA1(2);
+  C3 := AA1(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA1(1) := C1;
+  AA1(2) := C2;
+  AA1(3) := C3;
+  A1.A := AA1;
+
+  AA2 := A2.A;
+  C1 := AA2(1);
+  C2 := AA2(2);
+  C3 := AA2(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA2(1) := C1;
+  AA2(2) := C2;
+  AA2(3) := C3;
+  A2.A := AA2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+end;
Index: testsuite/gnat.dg/sso/s7.adb
===================================================================
--- testsuite/gnat.dg/sso/s7.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/s7.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,79 @@
+-- { dg-do run }
+
+with Init7; use Init7;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S7 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  N1 : Nested1;
+  N2 : Nested2;
+
+  C1 : Integer;
+  C2 : Integer;
+  C3 : Integer;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  N1 := A1.N;
+  C1 := N1.C1;
+  C2 := N1.C2;
+  C3 := N1.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  N1.C1 := C1;
+  N1.C2 := C2;
+  N1.C3 := C3;
+  A1.N := N1;
+
+  N2 := A2.N;
+  C1 := N2.C1;
+  C2 := N2.C2;
+  C3 := N2.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  N2.C1 := C1;
+  N2.C2 := C2;
+  N2.C3 := C3;
+  A2.N := N2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+end;
Index: testsuite/gnat.dg/sso/s8.adb
===================================================================
--- testsuite/gnat.dg/sso/s8.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/s8.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,79 @@
+-- { dg-do run }
+
+with Init8; use Init8;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S8 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  N1 : Nested1;
+  N2 : Nested2;
+
+  C1 : Integer;
+  C2 : Integer;
+  C3 : Integer;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  N1 := A1.N;
+  C1 := N1.C1;
+  C2 := N1.C2;
+  C3 := N1.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  N1.C1 := C1;
+  N1.C2 := C2;
+  N1.C3 := C3;
+  A1.N := N1;
+
+  N2 := A2.N;
+  C1 := N2.C1;
+  C2 := N2.C2;
+  C3 := N2.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  N2.C1 := C1;
+  N2.C2 := C2;
+  N2.C3 := C3;
+  A2.N := N2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+end;
Index: testsuite/gnat.dg/sso/dump.adb
===================================================================
--- testsuite/gnat.dg/sso/dump.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/dump.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,17 @@
+-- { dg-do compile }
+
+with Text_IO; use Text_IO;
+
+procedure Dump (A : System.Address; Len : Storage_Offset) is
+
+   Arr : Storage_Array (1 .. Len);
+   for Arr'Address use A;
+   pragma Import (Ada, Arr);
+
+   H : constant array (Storage_Element range 0 .. 15) of Character :=
+         "0123456789abcdef";
+begin
+   for J in Arr'Range loop
+      Put (' ' & H (Arr (J) / 16) & H (Arr (J) mod 16));
+   end loop;
+end;
Index: testsuite/gnat.dg/sso/sso.exp
===================================================================
--- testsuite/gnat.dg/sso/sso.exp	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/sso.exp	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,40 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib gnat-dg.exp
+load_lib torture-options.exp
+
+# Initialize `dg'.
+torture-init
+dg-init
+
+set SSO_TORTURE_OPTIONS [list \
+	{ -O0 } \
+	{ -O1 -fno-inline } \
+	{ -O2 } \
+	{ -O3 -finline-functions } \
+	{ -Os } \
+	{ -Og -g } ]
+
+set-torture-options $SSO_TORTURE_OPTIONS
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.adb]] "" ""
+
+# All done.
+dg-finish
+torture-finish
Index: testsuite/gnat.dg/sso/p1.adb
===================================================================
--- testsuite/gnat.dg/sso/p1.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p1.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,62 @@
+-- { dg-do run }
+
+with Init1; use Init1;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P1 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := 16#12345678#;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := 16#12345678#;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := Local_R2.I;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := Local_R1.I;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+end;
Index: testsuite/gnat.dg/sso/p2.adb
===================================================================
--- testsuite/gnat.dg/sso/p2.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p2.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,80 @@
+-- { dg-do run }
+
+with Init2; use Init2;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P2 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               A  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               A  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1.S1   := Local_R2.S1;
+  Local_R1.I    := Local_R2.I;
+  Local_R1.S2   := Local_R2.S2;
+  Local_R1.A(1) := Local_R2.A(1);
+  Local_R1.A(2) := Local_R2.A(2);
+  Local_R1.A(3) := Local_R2.A(3);
+  Local_R1.B    := Local_R2.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2.S1   := Local_R1.S1;
+  Local_R2.I    := Local_R1.I;
+  Local_R2.S2   := Local_R1.S2;
+  Local_R2.A(1) := Local_R1.A(1);
+  Local_R2.A(2) := Local_R1.A(2);
+  Local_R2.A(3) := Local_R1.A(3);
+  Local_R2.B    := Local_R1.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+end;
Index: testsuite/gnat.dg/sso/p3.adb
===================================================================
--- testsuite/gnat.dg/sso/p3.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p3.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,80 @@
+-- { dg-do run }
+
+with Init3; use Init3;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P3 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               N  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               N  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1.S1   := Local_R2.S1;
+  Local_R1.I    := Local_R2.I;
+  Local_R1.S2   := Local_R2.S2;
+  Local_R1.N.C1 := Local_R2.N.C1;
+  Local_R1.N.C2 := Local_R2.N.C2;
+  Local_R1.N.C3 := Local_R2.N.C3;
+  Local_R1.B    := Local_R2.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2.S1   := Local_R1.S1;
+  Local_R2.I    := Local_R1.I;
+  Local_R2.S2   := Local_R1.S2;
+  Local_R2.N.C1 := Local_R1.N.C1;
+  Local_R2.N.C2 := Local_R1.N.C2;
+  Local_R2.N.C3 := Local_R1.N.C3;
+  Local_R2.B    := Local_R1.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+end;
Index: testsuite/gnat.dg/sso/p4.adb
===================================================================
--- testsuite/gnat.dg/sso/p4.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p4.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,63 @@
+-- { dg-do run }
+
+with Init4; use Init4;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P4 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : db 0f 49 40\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 40 49 0f db\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db\n" }
+
+  Local_R1.F := Pi;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40\n" }
+
+  Local_R2.F := Pi;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db\n" }
+
+  Local_R1.F := Local_R2.F;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40\n" }
+
+  Local_R2.F := Local_R1.F;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db\n" }
+end;
Index: testsuite/gnat.dg/sso/p5.adb
===================================================================
--- testsuite/gnat.dg/sso/p5.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p5.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P5 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1.I    := Local_R2.I;
+  Local_R1.A(1) := Local_R2.A(1);
+  Local_R1.A(2) := Local_R2.A(2);
+  Local_R1.A(3) := Local_R2.A(3);
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2.I    := Local_R1.I;
+  Local_R2.A(1) := Local_R1.A(1);
+  Local_R2.A(2) := Local_R1.A(2);
+  Local_R2.A(3) := Local_R1.A(3);
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+end;
Index: testsuite/gnat.dg/sso/t1.adb
===================================================================
--- testsuite/gnat.dg/sso/t1.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t1.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,55 @@
+-- { dg-do run }
+
+with Init1; use Init1;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T1 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I := My_R1.I + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12\n" }
+
+  Local_R2.I := My_R2.I + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79\n" }
+
+  Local_R1.I := 16#12345678#;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := 16#12345678#;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := Local_R1.I + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12\n" }
+
+  Local_R2.I := Local_R2.I + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79\n" }
+
+end;
Index: testsuite/gnat.dg/sso/t2.adb
===================================================================
--- testsuite/gnat.dg/sso/t2.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t2.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,84 @@
+-- { dg-do run }
+
+with Init2; use Init2;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T2 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.S1 := My_R1.S1 - 1;
+  Local_R1.I := My_R1.I + 1;
+  Local_R1.S2 := My_R1.S2 - 1;
+  Local_R1.A(1) := My_R1.A(1) mod 16;
+  Local_R1.A(2) := My_R1.A(2) mod 16;
+  Local_R1.A(3) := My_R1.A(3) mod 16;
+  Local_R1.B := not My_R1.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" }
+
+  Local_R2.S1 := My_R2.S1 - 1;
+  Local_R2.I := My_R2.I + 1;
+  Local_R2.S2 := My_R2.S2 - 1;
+  Local_R2.A(1) := My_R2.A(1) mod 16;
+  Local_R2.A(2) := My_R2.A(2) mod 16;
+  Local_R2.A(3) := My_R2.A(3) mod 16;
+  Local_R2.B := not My_R2.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" }
+
+  Local_R1 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               A  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               A  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1.S1   := Local_R1.S1 - 1;
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.S2   := Local_R1.S2 - 1;
+  Local_R1.A(1) := Local_R1.A(1) mod 16;
+  Local_R1.A(2) := Local_R1.A(2) mod 16;
+  Local_R1.A(3) := Local_R1.A(3) mod 16;
+  Local_R1.B    := not Local_R1.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" }
+
+  Local_R2.S1   := Local_R2.S1 - 1;
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.S2   := Local_R2.S2 - 1;
+  Local_R2.A(1) := Local_R2.A(1) mod 16;
+  Local_R2.A(2) := Local_R2.A(2) mod 16;
+  Local_R2.A(3) := Local_R2.A(3) mod 16;
+  Local_R2.B    := not Local_R2.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" }
+end;
Index: testsuite/gnat.dg/sso/p6.adb
===================================================================
--- testsuite/gnat.dg/sso/p6.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p6.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,61 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P6 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1.I    := Local_R2.I;
+  Local_R1.A(1) := Local_R2.A(1);
+  Local_R1.A(2) := Local_R2.A(2);
+  Local_R1.A(3) := Local_R2.A(3);
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2.I    := Local_R1.I;
+  Local_R2.A(1) := Local_R1.A(1);
+  Local_R2.A(2) := Local_R1.A(2);
+  Local_R2.A(3) := Local_R1.A(3);
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+end;
Index: testsuite/gnat.dg/sso/t3.adb
===================================================================
--- testsuite/gnat.dg/sso/t3.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t3.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,84 @@
+-- { dg-do run }
+
+with Init3; use Init3;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T3 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.S1   := My_R1.S1 - 1;
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.S2   := My_R1.S2 - 1;
+  Local_R1.N.C1 := My_R1.N.C1 mod 16;
+  Local_R1.N.C2 := My_R1.N.C2 mod 16;
+  Local_R1.N.C3 := My_R1.N.C3 mod 16;
+  Local_R1.B    := not My_R1.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" }
+
+  Local_R2.S1   := My_R2.S1 - 1;
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.S2   := My_R2.S2 - 1;
+  Local_R2.N.C1 := My_R2.N.C1 mod 16;
+  Local_R2.N.C2 := My_R2.N.C2 mod 16;
+  Local_R2.N.C3 := My_R2.N.C3 mod 16;
+  Local_R2.B    := not My_R2.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" }
+
+  Local_R1 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               N  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               N  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1.S1   := Local_R1.S1 - 1;
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.S2   := Local_R1.S2 - 1;
+  Local_R1.N.C1 := Local_R1.N.C1 mod 16;
+  Local_R1.N.C2 := Local_R1.N.C2 mod 16;
+  Local_R1.N.C3 := Local_R1.N.C3 mod 16;
+  Local_R1.B    := not Local_R1.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" }
+
+  Local_R2.S1   := Local_R2.S1 - 1;
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.S2   := Local_R2.S2 - 1;
+  Local_R2.N.C1 := Local_R2.N.C1 mod 16;
+  Local_R2.N.C2 := Local_R2.N.C2 mod 16;
+  Local_R2.N.C3 := Local_R2.N.C3 mod 16;
+  Local_R2.B    := not Local_R2.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" }
+end;
Index: testsuite/gnat.dg/sso/dump.ads
===================================================================
--- testsuite/gnat.dg/sso/dump.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/dump.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,3 @@
+with System.Storage_Elements; use System.Storage_Elements;
+
+procedure Dump (A : System.Address; Len : Storage_Offset);
Index: testsuite/gnat.dg/sso/p7.adb
===================================================================
--- testsuite/gnat.dg/sso/p7.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p7.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,61 @@
+-- { dg-do run }
+
+with Init7; use Init7;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P7 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R1 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R2 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R1.I    := Local_R2.I;
+  Local_R1.N.C1 := Local_R2.N.C1;
+  Local_R1.N.C2 := Local_R2.N.C2;
+  Local_R1.N.C3 := Local_R2.N.C3;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R2.I    := Local_R1.I;
+  Local_R2.N.C1 := Local_R1.N.C1;
+  Local_R2.N.C2 := Local_R1.N.C2;
+  Local_R2.N.C3 := Local_R1.N.C3;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+end;
Index: testsuite/gnat.dg/sso/p8.adb
===================================================================
--- testsuite/gnat.dg/sso/p8.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p8.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,61 @@
+-- { dg-do run }
+
+with Init8; use Init8;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P8 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1.I    := Local_R2.I;
+  Local_R1.N.C1 := Local_R2.N.C1;
+  Local_R1.N.C2 := Local_R2.N.C2;
+  Local_R1.N.C3 := Local_R2.N.C3;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2.I    := Local_R1.I;
+  Local_R2.N.C1 := Local_R1.N.C1;
+  Local_R2.N.C2 := Local_R1.N.C2;
+  Local_R2.N.C3 := Local_R1.N.C3;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+end;
Index: testsuite/gnat.dg/sso/t4.adb
===================================================================
--- testsuite/gnat.dg/sso/t4.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t4.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,56 @@
+-- { dg-do run }
+
+with Init4; use Init4;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T4 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.F := My_R1.F + 1.0;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : ee 87 84 40\n" }
+
+  Local_R2.F := My_R2.F + 1.0;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 84 87 ee\n" }
+
+  Local_R1.F := Pi;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40\n" }
+
+  Local_R2.F := Pi;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db\n" }
+
+  Local_R1.F := Local_R1.F + 1.0;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : ee 87 84 40\n" }
+
+  Local_R2.F := Local_R2.F + 1.0;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 84 87 ee\n" }
+
+end;
Index: testsuite/gnat.dg/sso/p9.adb
===================================================================
--- testsuite/gnat.dg/sso/p9.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/p9.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,63 @@
+-- { dg-do run }
+
+with Init9; use Init9;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P9 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 18 2d 44 54 fb 21 09 40\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 40 09 21 fb 54 44 2d 18\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" }
+
+  Local_R1.F := Pi;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Local_R2.F := Pi;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" }
+
+  Local_R1.F := Local_R2.F;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Local_R2.F := Local_R1.F;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" }
+end;
Index: testsuite/gnat.dg/sso/t5.adb
===================================================================
--- testsuite/gnat.dg/sso/t5.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t5.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,67 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T5 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.A(1) := My_R1.A(1) + 1;
+  Local_R1.A(2) := My_R1.A(2) + 1;
+  Local_R1.A(3) := My_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.A(1) := My_R2.A(1) + 1;
+  Local_R2.A(2) := My_R2.A(2) + 1;
+  Local_R2.A(3) := My_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.A(1) := Local_R1.A(1) + 1;
+  Local_R1.A(2) := Local_R1.A(2) + 1;
+  Local_R1.A(3) := Local_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.A(1) := Local_R2.A(1) + 1;
+  Local_R2.A(2) := Local_R2.A(2) + 1;
+  Local_R2.A(3) := Local_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+end;
Index: testsuite/gnat.dg/sso/t6.adb
===================================================================
--- testsuite/gnat.dg/sso/t6.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso/t6.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,67 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T6 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.A(1) := My_R1.A(1) + 1;
+  Local_R1.A(2) := My_R1.A(2) + 1;
+  Local_R1.A(3) := My_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.A(1) := My_R2.A(1) + 1;
+  Local_R2.A(2) := My_R2.A(2) + 1;
+  Local_R2.A(3) := My_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.A(1) := Local_R1.A(1) + 1;
+  Local_R1.A(2) := Local_R1.A(2) + 1;
+  Local_R1.A(3) := Local_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.A(1) := Local_R2.A(1) + 1;
+  Local_R2.A(2) := Local_R2.A(2) + 1;
+  Local_R2.A(3) := Local_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+end;
Index: testsuite/gnat.dg/sso7.adb
===================================================================
--- testsuite/gnat.dg/sso7.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso7.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,52 @@
+-- { dg-do run }
+
+with System;
+
+procedure SSO7 is
+
+   type Short_Int is mod 2**16;
+
+   type Rec1 is record
+      F1 : Short_Int;
+      F2 : Short_Int;
+   end record;
+   for Rec1 use record
+      F1 at 0 range  0 .. 15;
+      F2 at 0 range 16 .. 31;
+   end record;
+   for Rec1'Bit_Order use System.High_Order_First;
+   for Rec1'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec2 is record
+      R1 : Rec1;
+   end record;
+   for Rec2 use record
+      R1 at 0 range 0 .. 31;
+   end record;
+   for Rec2'Bit_Order use System.High_Order_First;
+   for Rec2'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec3 is record
+      Data : Rec1;
+   end record;
+   for Rec3 use record
+      Data at 0 range 1 .. 32;
+   end record;
+   for Rec3'Bit_Order use System.High_Order_First;
+   for Rec3'Scalar_Storage_Order use System.High_Order_First;
+
+   procedure Copy (Message : in Rec3) is
+      Local : Rec2;
+   begin
+      Local := (R1 => Message.Data);
+      if Local.R1 /= Message.Data then
+         raise Program_Error;
+      end if;
+   end;
+
+   Message : Rec3;
+
+begin
+   Message := (Data => (2, 3));
+   Copy(Message);
+end;
Index: testsuite/gnat.dg/sso1.adb
===================================================================
--- testsuite/gnat.dg/sso1.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso1.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,77 @@
+-- { dg-do run }
+
+with System;
+with Ada.Unchecked_Conversion;
+with Ada.Streams; use Ada.Streams;
+with Ada.Text_IO;
+
+procedure SSO1 is
+
+   type Unsigned_Integer_4 is mod 2 ** 32;
+   for Unsigned_Integer_4'Size use 32;
+
+   Default_Bit_Order_Pos : constant Natural := System.Bit_Order'Pos (System.Default_Bit_Order);
+
+   Opposite_Bit_Order_Pos : constant Natural := 1 - Default_Bit_Order_Pos;
+
+   Opposite_Bit_Order : constant System.Bit_Order := System.Bit_Order'Val (Opposite_Bit_Order_Pos);
+
+   type Rec is
+      record
+	 X, Y : Unsigned_Integer_4;
+      end record;
+   for Rec'Bit_Order use System.Default_Bit_Order;
+   for Rec'Scalar_Storage_Order use System.Default_Bit_Order;
+
+   for Rec use
+      record
+	 X at 0 * 4 range 0 .. 31;
+	 Y at 1 * 4 range 0 .. 31;
+      end record;
+   
+   type Nested_Rec is
+      record 
+	 I : Unsigned_Integer_4;
+	 R : Rec;
+	 J : Unsigned_Integer_4;
+      end record;
+   for Nested_Rec use
+      record
+	 I at 0 * 4 range 0 .. 31;
+	 R at 1 * 4 range 0 .. 63;
+	 J at 3 * 4 range 0 .. 31;
+	 end record;
+
+   for Nested_Rec'Bit_Order use Opposite_Bit_Order;
+   for Nested_Rec'Scalar_Storage_Order use Opposite_Bit_Order;
+
+   Nr : Nested_Rec 
+     := (I => 1,
+	 R => (X => 1,
+	       Y => 1),
+	 J => 1);
+   
+   subtype Nested_Rec_As_Stream is Ada.Streams.Stream_Element_Array (1 ..16);
+
+   function To_Stream is
+     new Ada.Unchecked_Conversion (Nested_Rec, Nested_Rec_As_Stream);
+
+   Nr_Stream : constant Nested_Rec_As_Stream := To_Stream (Nr);
+
+   Expected : constant array (System.Bit_Order) of Nested_Rec_As_Stream :=
+                (System.Low_Order_First =>
+                   (0, 0, 0, 1,
+                    1, 0, 0, 0,
+                    1, 0, 0, 0,
+                    0, 0, 0, 1),
+                 System.High_Order_First =>
+                   (1, 0, 0, 0,
+                    0, 0, 0, 1,
+                    0, 0, 0, 1,
+                    1, 0, 0, 0));
+
+begin
+   if Nr_Stream /= Expected (System.Default_Bit_Order) then
+      raise Program_Error;
+   end if;
+end;
Index: testsuite/gnat.dg/sso2.adb
===================================================================
--- testsuite/gnat.dg/sso2.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso2.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,14 @@
+-- { dg-do compile }
+
+with Ada.Unchecked_Conversion;
+
+package body SSO2 is
+
+  function Conv is new Ada.Unchecked_Conversion (Arr1, Arr2);
+
+  procedure Proc (A1 : Arr1; A2 : out Arr2) is
+  begin
+     A2 := Conv (A1);
+  end;
+
+end SSO2;
Index: testsuite/gnat.dg/sso2.ads
===================================================================
--- testsuite/gnat.dg/sso2.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso2.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,13 @@
+with System;
+
+package SSO2 is
+
+  type Arr1 is array (1 .. 4) of Character;
+  for Arr1'Scalar_Storage_Order use System.High_Order_First;
+
+  type Arr2 is array (1 .. 4) of Character;
+  for Arr2'Scalar_Storage_Order use System.Low_Order_First;
+
+  procedure Proc (A1 : Arr1; A2 : out Arr2);
+
+end SSO2;
Index: testsuite/gnat.dg/sso3.adb
===================================================================
--- testsuite/gnat.dg/sso3.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso3.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,52 @@
+-- { dg-do run }
+
+with System; use System;
+
+procedure SSO3 is
+   Rev_SSO : constant Bit_Order
+     := Bit_Order'Val (1 - Bit_Order'Pos (Default_Bit_Order));
+
+   type R (D : Integer) is record
+      Common : Integer;
+      case D is
+         when 0 =>
+            V1 : Integer;
+         when others =>
+            V2 : Integer;
+      end case;
+   end record;
+
+   for R use record
+      D at 0 range 0 .. 31;
+      V1 at 4 range 0 .. 31;
+      V2 at 4 range 0 .. 31;
+      Common at 8 range 0 .. 31;
+   end record;
+   for R'Scalar_Storage_Order use Rev_SSO;
+   for R'Bit_Order use Rev_SSO;
+
+   procedure Check (Common, V : Integer; X : R) is
+   begin
+      if Common /= X.Common then
+         raise Program_Error;
+      end if;
+
+      case X.D is
+         when 0 =>
+            if V /= X.V1 then
+               raise Program_Error;
+            end if;
+         when others =>
+            if V /= X.V2 then
+               raise Program_Error;
+            end if;
+      end case;
+   end Check;
+
+   X0 : R := (D => 0,     Common => 1111, V1 => 1234);
+   X1 : R := (D => 31337, Common => 2222, V2 => 5678);
+
+begin
+   Check (1111, 1234, X0);
+   Check (2222, 5678, X1);
+end;
Index: testsuite/gnat.dg/sso4.adb
===================================================================
--- testsuite/gnat.dg/sso4.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso4.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,55 @@
+-- { dg-do run }
+
+with System;
+
+procedure SSO4 is
+
+   type Short_Int is mod 2**16;
+
+   type Rec1 is record
+      F1 : Short_Int;
+      F2 : Short_Int;
+   end record;
+   for Rec1 use record
+      F1 at 0 range  0 .. 15;
+      F2 at 0 range 16 .. 31;
+   end record;
+
+   for Rec1'Bit_Order use System.High_Order_First;
+   for Rec1'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec2 is record
+      I1 : Integer;
+      R1 : Rec1;
+   end record;
+   for Rec2 use record
+      I1 at 0 range 0 .. 31; 
+      R1 at 4 range 0 .. 31;
+   end record;
+   for Rec2'Bit_Order use System.High_Order_First;
+   for Rec2'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec3 is record
+      Data : Rec1;
+   end record;
+   for Rec3 use record
+      Data at 0 range  0 .. 31;
+   end record;
+   for Rec3'Bit_Order use System.High_Order_First;
+   for Rec3'Scalar_Storage_Order use System.High_Order_First;
+
+   procedure Copy (Message : in Rec3) is
+      Local : Rec2;
+   begin
+      Local := (I1 => 1, R1 => Message.Data);
+      if Local.R1 /= Message.Data then
+         raise Program_Error;
+      end if;
+   end;
+
+   Message : Rec3;
+
+begin
+   Message := (Data => (2, 3));
+   Copy(Message);
+end;
Index: testsuite/gnat.dg/specs/sso2.ads
===================================================================
--- testsuite/gnat.dg/specs/sso2.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/specs/sso2.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,26 @@
+-- { dg-do compile }
+-- { dg-options "-gnatws" }
+
+with System;
+
+package SSO2 is
+
+  I : Integer;
+
+  type Rec1 is record
+    A : System.Address;
+  end record;
+  for Rec1'Bit_Order use System.High_Order_First;
+  for Rec1'Scalar_Storage_Order use System.High_Order_First;
+
+  R1 : Rec1 := (A => I'Address);
+
+  type Rec2 is record
+    A : System.Address;
+  end record;
+  for Rec2'Bit_Order use System.Low_Order_First;
+  for Rec2'Scalar_Storage_Order use System.Low_Order_First;
+
+  R2 : Rec2 := (A => I'Address);
+
+end SSO2;
Index: testsuite/gnat.dg/specs/sso1.ads
===================================================================
--- testsuite/gnat.dg/specs/sso1.ads	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/specs/sso1.ads	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,22 @@
+-- { dg-do compile }
+
+with System;
+
+package SSO1 is
+
+   type R is record  -- { dg-error "inconsistent with bit order" }
+      B : Boolean;
+   end record;
+   for R'Bit_Order use System.Low_Order_First;
+   for R'Scalar_Storage_Order use System.High_Order_First;
+   for R use record
+      B at 0 range 0 .. 1;
+   end record;
+
+   type RW is record
+      B : Boolean;
+   end record;
+   for RW'Bit_Order use System.Low_Order_First;
+   for RW'Scalar_Storage_Order use System.Low_Order_First;  -- { dg-warning "no component clause" }
+
+end SSO1;
Index: testsuite/gnat.dg/sso5.adb
===================================================================
--- testsuite/gnat.dg/sso5.adb	(.../trunk/gcc)	(revision 0)
+++ testsuite/gnat.dg/sso5.adb	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,52 @@
+-- { dg-do run }
+
+with System;
+
+procedure SSO5 is
+
+   type Short_Int is mod 2**16;
+
+   type Rec1 is record
+      F1 : Short_Int;
+      F2 : Short_Int;
+   end record;
+   for Rec1 use record
+      F1 at 0 range  0 .. 15;
+      F2 at 0 range 16 .. 31;
+   end record;
+   for Rec1'Bit_Order use System.High_Order_First;
+   for Rec1'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec2 is record
+      R1 : Rec1;
+   end record;
+   for Rec2 use record
+      R1 at 0 range 1 .. 32;
+   end record;
+   for Rec2'Bit_Order use System.High_Order_First;
+   for Rec2'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec3 is record
+      Data : Rec1;
+   end record;
+   for Rec3 use record
+      Data at 0 range 0 .. 31;
+   end record;
+   for Rec3'Bit_Order use System.High_Order_First;
+   for Rec3'Scalar_Storage_Order use System.High_Order_First;
+
+   procedure Copy (Message : in Rec3) is
+      Local : Rec2;
+   begin
+      Local := (R1 => Message.Data);
+      if Local.R1 /= Message.Data then
+         raise Program_Error;
+      end if;
+   end;
+
+   Message : Rec3;
+
+begin
+   Message := (Data => (2, 3));
+   Copy(Message);
+end;
Index: testsuite/gcc.dg/sso/sso.exp
===================================================================
--- testsuite/gcc.dg/sso/sso.exp	(.../trunk/gcc)	(revision 0)
+++ testsuite/gcc.dg/sso/sso.exp	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,40 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib gcc-dg.exp
+load_lib torture-options.exp
+
+# Initialize `dg'.
+torture-init
+dg-init
+
+set SSO_TORTURE_OPTIONS [list \
+	{ -O0 } \
+	{ -O1 -fno-inline } \
+	{ -O2 } \
+	{ -O3 -finline-functions } \
+	{ -Os } \
+	{ -Og -g } ]
+
+set-torture-options $SSO_TORTURE_OPTIONS
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/sso/*.c]] "" ""
+
+# All done.
+dg-finish
+torture-finish
Index: testsuite/gcc.dg/sso-1.c
===================================================================
--- testsuite/gcc.dg/sso-1.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/gcc.dg/sso-1.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+int i;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+struct __attribute__((scalar_storage_order("big-endian"))) Rec
+{
+  int *p;
+};
+#else
+struct __attribute__((scalar_storage_order("little-endian"))) Rec
+{
+  int *p;
+};
+#endif
+
+struct Rec r = { &i };  /* { dg-error "element is not constant" } */
Index: testsuite/g++.dg/sso/sso.exp
===================================================================
--- testsuite/g++.dg/sso/sso.exp	(.../trunk/gcc)	(revision 0)
+++ testsuite/g++.dg/sso/sso.exp	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,40 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib g++-dg.exp
+load_lib torture-options.exp
+
+# Initialize `dg'.
+torture-init
+dg-init
+
+set SSO_TORTURE_OPTIONS [list \
+	{ -O0 } \
+	{ -O1 -fno-inline } \
+	{ -O2 } \
+	{ -O3 -finline-functions } \
+	{ -Os } \
+	{ -Og -g } ]
+
+set-torture-options $SSO_TORTURE_OPTIONS
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/sso/*.c]] "" ""
+
+# All done.
+dg-finish
+torture-finish
Index: testsuite/g++.dg/sso-1.C
===================================================================
--- testsuite/g++.dg/sso-1.C	(.../trunk/gcc)	(revision 0)
+++ testsuite/g++.dg/sso-1.C	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,17 @@
+// { dg-do compile }
+
+int i;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+struct __attribute__((scalar_storage_order("big-endian"))) Rec
+{
+  int *p;
+};
+#else
+struct __attribute__((scalar_storage_order("little-endian"))) Rec
+{
+  int *p;
+};
+#endif
+
+struct Rec r = { &i };
Index: testsuite/c-c++-common/sso-2.c
===================================================================
--- testsuite/c-c++-common/sso-2.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso-2.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,94 @@
+/* Test support of scalar_storage_order attribute */
+
+/* { dg-do compile } */
+
+struct S1
+{
+  int i;
+} __attribute__((scalar_storage_order("big-endian")));
+
+struct S2
+{
+  int i;
+} __attribute__((scalar_storage_order("little-endian")));
+
+struct S3 { int i; } __attribute__((scalar_storage_order("other"))); /* { dg-error "must be one of .big-endian. or .little-endian." } */
+
+void incompatible_assign (struct S1 *s1, struct S2 *s2)
+{
+  *s1 = *s2; /* { dg-error "(incompatible types|no match)" } */
+}
+
+int *addr1 (int which, struct S1 *s1, struct S2 *s2)
+{
+  return (which == 1 ? &s1->i : &s2->i); /* { dg-error "address of scalar with reverse storage order" } */
+}
+
+struct S4
+{
+  int a[4];
+  struct S2 s2;
+} __attribute__((scalar_storage_order("big-endian")));
+
+struct S5
+{
+  int a[4];
+  struct S1 s1;
+} __attribute__((scalar_storage_order("little-endian")));
+
+void *addr2 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)s4->a : (void *)s5->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr3 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)&s4->a : (void *)&s5->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr4 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)&s4->a[0] : (void *)&s5->a[0]); /* { dg-error "address of scalar with reverse storage order" } */
+}
+
+void *addr5 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)&s4->s2 : (void *) &s5->s1); /* ok */
+}
+
+struct S6
+{
+  int a[4][2];
+  struct S2 s2[2];
+}  __attribute__((scalar_storage_order("big-endian")));
+
+struct S7
+{
+  int a[4][2];
+  struct S1 s1[2];
+}  __attribute__((scalar_storage_order("little-endian")));
+
+void *addr6 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)s6->a : (void *)s7->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr7 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->a : (void *)&s7->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr8 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->a[0] : (void *)&s7->a[0]); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr9 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->a[0][0] : (void *)&s7->a[0][0]); /* { dg-error "address of scalar with reverse storage order" } */
+}
+
+void *addr10 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->s2 : (void *)&s7->s1); /* ok */
+}
Index: testsuite/c-c++-common/sso-6.c
===================================================================
--- testsuite/c-c++-common/sso-6.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso-6.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,44 @@
+/* Test support of scalar_storage_order pragma */
+
+/* { dg-do run } */
+/* { dg-options "-fsso-struct=big-endian" } */
+
+struct S1
+{
+  int i;
+};
+
+#pragma scalar_storage_order little-endian
+
+struct S2
+{
+  int i;
+};
+
+#pragma scalar_storage_order default
+
+struct S3
+{
+  int i;
+};
+
+struct S1 my_s1 = { 0x12345678 };
+struct S2 my_s2 = { 0x12345678 };
+struct S3 my_s3 = { 0x12345678 };
+
+unsigned char big_endian_pattern[4] = { 0x12, 0x34, 0x56, 0x78 };
+unsigned char little_endian_pattern[4] = { 0x78, 0x56, 0x34, 0x12 };
+
+int main (void)
+{
+  if (__builtin_memcmp (&my_s1, &big_endian_pattern, 4) != 0)
+    __builtin_abort ();
+
+  if (__builtin_memcmp (&my_s2, &little_endian_pattern, 4) != 0)
+    __builtin_abort ();
+
+  if (__builtin_memcmp (&my_s3, &big_endian_pattern, 4) != 0)
+    __builtin_abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso-3.c
===================================================================
--- testsuite/c-c++-common/sso-3.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso-3.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,21 @@
+/* Test support of scalar_storage_order attribute */
+
+/* { dg-do compile } */
+
+struct S1
+{
+  int i;
+};
+
+typedef struct S1 __attribute__((scalar_storage_order("big-endian"))) NS1; /* { dg-warning "attribute ignored" } */
+
+struct S2
+{
+  int i;
+};
+
+typedef struct S2 __attribute__((scalar_storage_order("little-endian"))) NS2; /* { dg-warning "attribute ignored" } */
+
+struct S3 { int i; };
+
+typedef struct S3 __attribute__((scalar_storage_order("other"))) NS3; /* { dg-warning "attribute ignored" } */
Index: testsuite/c-c++-common/sso-7.c
===================================================================
--- testsuite/c-c++-common/sso-7.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso-7.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,44 @@
+/* Test support of scalar_storage_order pragma */
+
+/* { dg-do run } */
+/* { dg-options "-fsso-struct=little-endian" } */
+
+struct S1
+{
+  int i;
+};
+
+#pragma scalar_storage_order big-endian
+
+struct S2
+{
+  int i;
+};
+
+#pragma scalar_storage_order default
+
+struct S3
+{
+  int i;
+};
+
+struct S1 my_s1 = { 0x12345678 };
+struct S2 my_s2 = { 0x12345678 };
+struct S3 my_s3 = { 0x12345678 };
+
+unsigned char big_endian_pattern[4] = { 0x12, 0x34, 0x56, 0x78 };
+unsigned char little_endian_pattern[4] = { 0x78, 0x56, 0x34, 0x12 };
+
+int main (void)
+{
+  if (__builtin_memcmp (&my_s1, &little_endian_pattern, 4) != 0)
+    __builtin_abort ();
+
+  if (__builtin_memcmp (&my_s2, &big_endian_pattern, 4) != 0)
+    __builtin_abort ();
+
+  if (__builtin_memcmp (&my_s3, &little_endian_pattern, 4) != 0)
+    __builtin_abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/init6.h
===================================================================
--- testsuite/c-c++-common/sso/init6.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/init6.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,24 @@
+struct __attribute__((scalar_storage_order("big-endian"))) Nested1
+{
+  int A[3];
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  int I;
+  struct Nested1 N;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) Nested2
+{
+  int A[3];
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  int I;
+  struct Nested2 N;
+};
+
+struct R1 My_R1 = { 0x12345678, { { 0xAB0012, 0xCD0034, 0xEF0056 } } };
+struct R2 My_R2 = { 0x12345678, { { 0xAB0012, 0xCD0034, 0xEF0056 } } };
Index: testsuite/c-c++-common/sso/init7.h
===================================================================
--- testsuite/c-c++-common/sso/init7.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/init7.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,28 @@
+struct __attribute__((scalar_storage_order("little-endian"))) Nested1
+{
+  int C1;
+  int C2;
+  int C3;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  int I;
+  struct Nested1 N;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) Nested2
+{
+  int C1;
+  int C2;
+  int C3;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  int I;
+  struct Nested2 N;
+};
+
+struct R1 My_R1 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
+struct R2 My_R2 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
Index: testsuite/c-c++-common/sso/init8.h
===================================================================
--- testsuite/c-c++-common/sso/init8.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/init8.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,28 @@
+struct __attribute__((scalar_storage_order("big-endian"))) Nested1
+{
+  int C1;
+  int C2;
+  int C3;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  int I;
+  struct Nested1 N;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) Nested2
+{
+  int C1;
+  int C2;
+  int C3;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  int I;
+  struct Nested2 N;
+};
+
+struct R1 My_R1 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
+struct R2 My_R2 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
Index: testsuite/c-c++-common/sso/init9.h
===================================================================
--- testsuite/c-c++-common/sso/init9.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/init9.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,14 @@
+#define Pi 3.14159265358979323846
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  double F;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  double F;
+};
+
+struct R1 My_R1 = { Pi };
+struct R2 My_R2 = { Pi };
Index: testsuite/c-c++-common/sso/p13.c
===================================================================
--- testsuite/c-c++-common/sso/p13.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/p13.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,64 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init13.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : db 0f 49 40 db 0f 49 c0\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 40 49 0f db c0 49 0f db\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40 db 0f 49 c0\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db c0 49 0f db\n" } */
+
+  Local_R1.F = Pi - Pi * I;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40 db 0f 49 c0\n" } */
+
+  Local_R2.F = Pi - Pi * I;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db c0 49 0f db\n" } */
+
+  Local_R1.F = Local_R2.F;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40 db 0f 49 c0\n" } */
+
+  Local_R2.F = Local_R1.F;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db c0 49 0f db\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/q13.c
===================================================================
--- testsuite/c-c++-common/sso/q13.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/q13.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init13.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : db 0f 49 40 db 0f 49 c0\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : db 0f 49 40 db 0f 49 c0\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 40 49 0f db c0 49 0f db\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 40 49 0f db c0 49 0f db\n" } */
+
+  if (A1.F != B1.F) abort ();
+
+  if (A1.F != Pi - Pi * I) abort ();
+
+  if (A2.F != B2.F) abort ();
+
+  if (A2.F != Pi - Pi * I) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/t13.c
===================================================================
--- testsuite/c-c++-common/sso/t13.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/t13.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init13.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.F = My_R1.F + (1.0f + 1.0f * I);
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : ee 87 84 40 db 0f 09 c0\n" } */
+
+  Local_R2.F = My_R2.F + (1.0f + 1.0f * I);
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 84 87 ee c0 09 0f db\n" } */
+
+  Local_R1.F = Pi - Pi * I;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40 db 0f 49 c0\n" } */
+
+  Local_R2.F = Pi - Pi * I;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db c0 49 0f db\n" } */
+
+  Local_R1.F = Local_R1.F + (1.0f + 1.0f * I);
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : ee 87 84 40 db 0f 09 c0\n" } */
+
+  Local_R2.F = Local_R2.F + (1.0f + 1.0f * I);
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 84 87 ee c0 09 0f db\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/init13.h
===================================================================
--- testsuite/c-c++-common/sso/init13.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/init13.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,15 @@
+#define I (__extension__ 1.0iF)
+#define Pi 3.1415927f
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  _Complex float F;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  _Complex float F;
+};
+
+struct R1 My_R1 = { Pi - Pi * I };
+struct R2 My_R2 = { Pi - Pi * I };
Index: testsuite/c-c++-common/sso/q1.c
===================================================================
--- testsuite/c-c++-common/sso/q1.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/q1.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init1.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 78 56 34 12\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 12 34 56 78\n" } */
+
+  if (A1.I != B1.I) abort ();
+
+  if (A1.I != 0x12345678) abort ();
+
+  if (A2.I != B2.I) abort ();
+
+  if (A2.I != 0x12345678) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/q2.c
===================================================================
--- testsuite/c-c++-common/sso/q2.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/q2.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,54 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init2.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  if (A1.S1 != B1.S1) abort ();
+
+  if (A1.S1 != 2) abort ();
+
+  if (A2.S1 != B2.S1) abort ();
+
+  if (A2.S1 != 2) abort ();
+
+  if (A1.I != B1.I || A1.A1 != B1.A1) abort ();
+
+  if (A2.I != B2.I || A2.A1 != B2.A1) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/q3.c
===================================================================
--- testsuite/c-c++-common/sso/q3.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/q3.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,54 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init3.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  if (A1.S1 != B1.S1) abort ();
+
+  if (A1.S1 != 2) abort ();
+
+  if (A2.S1 != B2.S1) abort ();
+
+  if (A2.S1 != 2) abort ();
+
+  if (A1.I != B1.I || A1.N.C1 != B1.N.C1) abort ();
+
+  if (A2.I != B2.I || A2.N.C1 != B2.N.C1) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/q4.c
===================================================================
--- testsuite/c-c++-common/sso/q4.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/q4.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init4.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : db 0f 49 40\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : db 0f 49 40\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 40 49 0f db\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 40 49 0f db\n" } */
+
+  if (A1.F != B1.F) abort ();
+
+  if (A1.F != Pi) abort ();
+
+  if (A2.F != B2.F) abort ();
+
+  if (A2.F != Pi) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/q5.c
===================================================================
--- testsuite/c-c++-common/sso/q5.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/q5.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  if (A1.I != B1.I || A1.A[0] != B1.A[0]) abort();
+
+  if (A2.I != B2.I || A2.A[0] != B2.A[0]) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/s3.c
===================================================================
--- testsuite/c-c++-common/sso/s3.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/s3.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,79 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init3.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  struct Nested1 N1;
+  struct Nested2 N2;
+
+  unsigned C1;
+  unsigned C2;
+  unsigned C3;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  N1 = A1.N;
+  C1 = N1.C1;
+  C2 = N1.C2;
+  C3 = N1.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 18\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 52\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 86\n" } */
+
+  N1.C1 = C1;
+  N1.C2 = C2;
+  N1.C3 = C3;
+  A1.N = N1;
+
+  N2 = A2.N;
+  C1 = N2.C1;
+  C2 = N2.C2;
+  C3 = N2.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 18\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 52\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 86\n" } */
+
+  N2.C1 = C1;
+  N2.C2 = C2;
+  N2.C3 = C3;
+  A2.N = N2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/q6.c
===================================================================
--- testsuite/c-c++-common/sso/q6.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/q6.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  if (A1.I != B1.I || A1.N.A[0] != B1.N.A[0]) abort();
+
+  if (A2.I != B2.I || A2.N.A[0] != B2.N.A[0]) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/s5.c
===================================================================
--- testsuite/c-c++-common/sso/s5.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/s5.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,91 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+#pragma GCC diagnostic ignored "-Wscalar-storage-order"
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  struct __attribute__((scalar_storage_order("little-endian"))) Nested1
+  {
+    int A[3];
+  };
+
+  struct __attribute__((scalar_storage_order("big-endian"))) Nested2
+  {
+    int A[3];
+  };
+
+  struct Nested1 N1;
+  struct Nested2 N2;
+
+  int C1;
+  int C2;
+  int C3;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  __builtin_memcpy (N1.A, A1.A, sizeof (int) * 3);
+  C1 = N1.A[0];
+  C2 = N1.A[1];
+  C3 = N1.A[2];
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N1.A[0] = C1;
+  N1.A[1] = C2;
+  N1.A[2] = C3;
+  __builtin_memcpy (A1.A, N1.A, sizeof (int) * 3);
+
+  __builtin_memcpy (N2.A, A2.A, sizeof (int) * 3);
+  C1 = N2.A[0];
+  C2 = N2.A[1];
+  C3 = N2.A[2];
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N2.A[0] = C1;
+  N2.A[1] = C2;
+  N2.A[2] = C3;
+  __builtin_memcpy (A2.A, N2.A, sizeof (int) * 3);
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/q7.c
===================================================================
--- testsuite/c-c++-common/sso/q7.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/q7.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init7.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  if (A1.I != B1.I || A1.N.C1 != B1.N.C1) abort();
+
+  if (A2.I != B2.I || A2.N.C1 != B2.N.C1) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/s6.c
===================================================================
--- testsuite/c-c++-common/sso/s6.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/s6.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,81 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+#pragma GCC diagnostic ignored "-Wscalar-storage-order"
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  struct Nested1 N1;
+  struct Nested2 N2;
+
+  int C1;
+  int C2;
+  int C3;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  __builtin_memcpy (N1.A, A1.N.A, sizeof (int) * 3);
+  C1 = N1.A[0];
+  C2 = N1.A[1];
+  C3 = N1.A[2];
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N1.A[0] = C1;
+  N1.A[1] = C2;
+  N1.A[2] = C3;
+  __builtin_memcpy (A1.N.A, N1.A, sizeof (int) * 3);
+
+  __builtin_memcpy (N2.A, A2.N.A, sizeof (int) * 3);
+  C1 = N2.A[0];
+  C2 = N2.A[1];
+  C3 = N2.A[2];
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N2.A[0] = C1;
+  N2.A[1] = C2;
+  N2.A[2] = C3;
+  __builtin_memcpy (A2.N.A, N2.A, sizeof (int) * 3);
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/q8.c
===================================================================
--- testsuite/c-c++-common/sso/q8.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/q8.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init8.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  if (A1.I != B1.I || A1.N.C1 != B1.N.C1) abort();
+
+  if (A2.I != B2.I || A2.N.C1 != B2.N.C1) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/u5.c
===================================================================
--- testsuite/c-c++-common/sso/u5.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/u5.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+  int C1;
+  int C2;
+
+  Local_R1.I    = 1;
+  Local_R1.A[0] = 0xAB0012;
+  Local_R1.A[1] = 0xCD0034;
+  Local_R1.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 01 00 00 00 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = 1;
+  Local_R2.A[0] = 0xAB0012;
+  Local_R2.A[1] = 0xCD0034;
+  Local_R2.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 00 00 00 01 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  C1 = Local_R1.A[Local_R1.I];
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 13434932\n" } */
+
+  Local_R1.I++;
+  C1 = Local_R1.A[Local_R1.I];
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 15663190\n" } */
+
+  C2 = Local_R2.A[Local_R2.I];
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  Local_R2.I++;
+  C2 = Local_R2.A[Local_R2.I];
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 15663190\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/s7.c
===================================================================
--- testsuite/c-c++-common/sso/s7.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/s7.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,79 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init7.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  struct Nested1 N1;
+  struct Nested2 N2;
+
+  int C1;
+  int C2;
+  int C3;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  N1 = A1.N;
+  C1 = N1.C1;
+  C2 = N1.C2;
+  C3 = N1.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N1.C1 = C1;
+  N1.C2 = C2;
+  N1.C3 = C3;
+  A1.N = N1;
+
+  N2 = A2.N;
+  C1 = N2.C1;
+  C2 = N2.C2;
+  C3 = N2.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N2.C1 = C1;
+  N2.C2 = C2;
+  N2.C3 = C3;
+  A2.N = N2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/q9.c
===================================================================
--- testsuite/c-c++-common/sso/q9.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/q9.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init9.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  if (A1.F != B1.F) abort ();
+
+  if (A1.F != Pi) abort ();
+
+  if (A2.F != B2.F) abort ();
+
+  if (A2.F != Pi) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/u6.c
===================================================================
--- testsuite/c-c++-common/sso/u6.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/u6.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+  int C1;
+  int C2;
+
+  Local_R1.I      = 1;
+  Local_R1.N.A[0] = 0xAB0012;
+  Local_R1.N.A[1] = 0xCD0034;
+  Local_R1.N.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 01 00 00 00 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I      = 1;
+  Local_R2.N.A[0] = 0xAB0012;
+  Local_R2.N.A[1] = 0xCD0034;
+  Local_R2.N.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 00 00 00 01 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  C1 = Local_R1.N.A[Local_R1.I];
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 13434932\n" } */
+
+  Local_R1.I++;
+  C1 = Local_R1.N.A[Local_R1.I];
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 15663190\n" } */
+
+  C2 = Local_R2.N.A[Local_R2.I];
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  Local_R2.I++;
+  C2 = Local_R2.N.A[Local_R2.I];
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 15663190\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/s8.c
===================================================================
--- testsuite/c-c++-common/sso/s8.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/s8.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,79 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init8.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  struct Nested1 N1;
+  struct Nested2 N2;
+
+  int C1;
+  int C2;
+  int C3;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  N1 = A1.N;
+  C1 = N1.C1;
+  C2 = N1.C2;
+  C3 = N1.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N1.C1 = C1;
+  N1.C2 = C2;
+  N1.C3 = C3;
+  A1.N = N1;
+
+  N2 = A2.N;
+  C1 = N2.C1;
+  C2 = N2.C2;
+  C3 = N2.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N2.C1 = C1;
+  N2.C2 = C2;
+  N2.C3 = C3;
+  A2.N = N2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/dump.h
===================================================================
--- testsuite/c-c++-common/sso/dump.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/dump.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,23 @@
+void dump (void *p, unsigned int len)
+{
+  const char digits[17] = "0123456789abcdef";
+  unsigned char *a = (unsigned char *)p;
+  int i;
+
+  for (i = 0; i < len; i++)
+    {
+      putchar (' ');
+      putchar (digits[a[i] / 16]);
+      putchar (digits[a[i] % 16]);
+    }
+}
+
+void put (const char s[])
+{
+  fputs (s, stdout);
+}
+
+void new_line (void)
+{
+  putchar ('\n');
+}
Index: testsuite/c-c++-common/sso/p1.c
===================================================================
--- testsuite/c-c++-common/sso/p1.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/p1.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,64 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init1.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 78 56 34 12\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 12 34 56 78\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78\n" } */
+
+  Local_R1.I = 0x12345678;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12\n" } */
+
+  Local_R2.I = 0x12345678;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78\n" } */
+
+  Local_R1.I = Local_R2.I;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12\n" } */
+
+  Local_R2.I = Local_R1.I;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/p2.c
===================================================================
--- testsuite/c-c++-common/sso/p2.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/p2.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,88 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init2.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  Local_R1.S1 = 2;
+  Local_R1.I  = 0x12345678;
+  Local_R1.S2 = 1;
+  Local_R1.A1 = 0xAB;
+  Local_R1.A2 = 0xCD;
+  Local_R1.A3 = 0xEF;
+  Local_R1.B  = 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  Local_R2.S1 = 2;
+  Local_R2.I  = 0x12345678;
+  Local_R2.S2 = 1;
+  Local_R2.A1 = 0xAB;
+  Local_R2.A2 = 0xCD;
+  Local_R2.A3 = 0xEF;
+  Local_R2.B  = 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  Local_R1.S1 = Local_R2.S1;
+  Local_R1.I  = Local_R2.I;
+  Local_R1.S2 = Local_R2.S2;
+  Local_R1.A1 = Local_R2.A1;
+  Local_R1.A2 = Local_R2.A2;
+  Local_R1.A3 = Local_R2.A3;
+  Local_R1.B  = Local_R2.B;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  Local_R2.S1 = Local_R1.S1;
+  Local_R2.I  = Local_R1.I;
+  Local_R2.S2 = Local_R1.S2;
+  Local_R2.A1 = Local_R1.A1;
+  Local_R2.A2 = Local_R1.A2;
+  Local_R2.A3 = Local_R1.A3;
+  Local_R2.B  = Local_R1.B;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/p3.c
===================================================================
--- testsuite/c-c++-common/sso/p3.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/p3.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,88 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init3.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  Local_R1.S1   = 2;
+  Local_R1.I    = 0x78ABCDEF;
+  Local_R1.S2   = 1;
+  Local_R1.N.C1 = 0x12;
+  Local_R1.N.C2 = 0x34;
+  Local_R1.N.C3 = 0x56;
+  Local_R1.N.B  = 4;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  Local_R2.S1   = 2;
+  Local_R2.I    = 0x78ABCDEF;
+  Local_R2.S2   = 1;
+  Local_R2.N.C1 = 0x12;
+  Local_R2.N.C2 = 0x34;
+  Local_R2.N.C3 = 0x56;
+  Local_R2.N.B  = 4;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  Local_R1.S1   = Local_R2.S1;
+  Local_R1.I    = Local_R2.I;
+  Local_R1.S2   = Local_R2.S2;
+  Local_R1.N.C1 = Local_R2.N.C1;
+  Local_R1.N.C2 = Local_R2.N.C2;
+  Local_R1.N.C3 = Local_R2.N.C3;
+  Local_R1.N.B  = Local_R2.N.B;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  Local_R2.S1   = Local_R1.S1;
+  Local_R2.I    = Local_R1.I;
+  Local_R2.S2   = Local_R1.S2;
+  Local_R2.N.C1 = Local_R1.N.C1;
+  Local_R2.N.C2 = Local_R1.N.C2;
+  Local_R2.N.C3 = Local_R1.N.C3;
+  Local_R2.N.B  = Local_R1.N.B;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/p4.c
===================================================================
--- testsuite/c-c++-common/sso/p4.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/p4.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,64 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init4.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : db 0f 49 40\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 40 49 0f db\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db\n" } */
+
+  Local_R1.F = Pi;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40\n" } */
+
+  Local_R2.F = Pi;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db\n" } */
+
+  Local_R1.F = Local_R2.F;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40\n" } */
+
+  Local_R2.F = Local_R1.F;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/t1.c
===================================================================
--- testsuite/c-c++-common/sso/t1.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/t1.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init1.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.I = My_R1.I + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12\n" } */
+
+  Local_R2.I = My_R2.I + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79\n" } */
+
+  Local_R1.I = 0x12345678;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12\n" } */
+
+  Local_R2.I = 0x12345678;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78\n" } */
+
+  Local_R1.I = Local_R1.I + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12\n" } */
+
+  Local_R2.I = Local_R2.I + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/p5.c
===================================================================
--- testsuite/c-c++-common/sso/p5.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/p5.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.A[0] = 0xAB0012;
+  Local_R1.A[1] = 0xCD0034;
+  Local_R1.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.A[0] = 0xAB0012;
+  Local_R2.A[1] = 0xCD0034;
+  Local_R2.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = Local_R2.I;
+  Local_R1.A[0] = Local_R2.A[0];
+  Local_R1.A[1] = Local_R2.A[1];
+  Local_R1.A[2] = Local_R2.A[2];
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = Local_R1.I;
+  Local_R2.A[0] = Local_R1.A[0];
+  Local_R2.A[1] = Local_R1.A[1];
+  Local_R2.A[2] = Local_R1.A[2];
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/r3.c
===================================================================
--- testsuite/c-c++-common/sso/r3.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/r3.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init3.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int Get_Elem1 (struct R1 R)
+{
+  struct R1 Tmp = R;
+  return Tmp.I;
+}
+
+void Set_Elem1 (struct R1 *R, int I)
+{
+  struct R1 Tmp = *R;
+  Tmp.I = I;
+  *R = Tmp;
+}
+
+int Get_Elem2 (struct R2 R)
+{
+  struct R2 Tmp = R;
+  return Tmp.I;
+}
+
+void Set_Elem2 (struct R2 *R, int I)
+{
+  struct R2 Tmp = *R;
+  Tmp.I = I;
+  *R = Tmp;
+}
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  if (Get_Elem1 (A1) != 0x78ABCDEF) abort ();
+
+  Set_Elem1 (&A1, 0xCD0034);
+  if (Get_Elem1 (A1) != 0xCD0034) abort ();
+
+  if (Get_Elem2 (A2) != 0x78ABCDEF) abort ();
+
+  Set_Elem2 (&A2, 0xCD0034);
+  if (Get_Elem2 (A2) != 0xCD0034) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/p6.c
===================================================================
--- testsuite/c-c++-common/sso/p6.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/p6.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I      = 0x12345678;
+  Local_R1.N.A[0] = 0xAB0012;
+  Local_R1.N.A[1] = 0xCD0034;
+  Local_R1.N.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I      = 0x12345678;
+  Local_R2.N.A[0] = 0xAB0012;
+  Local_R2.N.A[1] = 0xCD0034;
+  Local_R2.N.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I      = Local_R2.I;
+  Local_R1.N.A[0] = Local_R2.N.A[0];
+  Local_R1.N.A[1] = Local_R2.N.A[1];
+  Local_R1.N.A[2] = Local_R2.N.A[2];
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I      = Local_R1.I;
+  Local_R2.N.A[0] = Local_R1.N.A[0];
+  Local_R2.N.A[1] = Local_R1.N.A[1];
+  Local_R2.N.A[2] = Local_R1.N.A[2];
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/t2.c
===================================================================
--- testsuite/c-c++-common/sso/t2.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/t2.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,92 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init2.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.S1 = My_R1.S1 - 1;
+  Local_R1.I  = My_R1.I + 1;
+  Local_R1.S2 = My_R1.S2 - 1;
+  Local_R1.A1 = My_R1.A1 % 16;
+  Local_R1.A2 = My_R1.A2 % 16;
+  Local_R1.A3 = My_R1.A3 % 16;
+  Local_R1.B  = !My_R1.B;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" } */
+
+  Local_R2.S1 = My_R2.S1 - 1;
+  Local_R2.I  = My_R2.I + 1;
+  Local_R2.S2 = My_R2.S2 - 1;
+  Local_R2.A1 = My_R2.A1 % 16;
+  Local_R2.A2 = My_R2.A2 % 16;
+  Local_R2.A3 = My_R2.A3 % 16;
+  Local_R2.B  = !My_R2.B;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" } */
+
+  Local_R1.S1 = 2;
+  Local_R1.I  = 0x12345678;
+  Local_R1.S2 = 1;
+  Local_R1.A1 = 0xAB;
+  Local_R1.A2 = 0xCD;
+  Local_R1.A3 = 0xEF;
+  Local_R1.B  = 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  Local_R2.S1 = 2;
+  Local_R2.I  = 0x12345678;
+  Local_R2.S2 = 1;
+  Local_R2.A1 = 0xAB;
+  Local_R2.A2 = 0xCD;
+  Local_R2.A3 = 0xEF;
+  Local_R2.B  = 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  Local_R1.S1 = Local_R1.S1 - 1;
+  Local_R1.I  = Local_R1.I + 1;
+  Local_R1.S2 = Local_R1.S2 - 1;
+  Local_R1.A1 = Local_R1.A1 % 16;
+  Local_R1.A2 = Local_R1.A2 % 16;
+  Local_R1.A3 = Local_R1.A3 % 16;
+  Local_R1.B  = !Local_R1.B;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" } */
+
+  Local_R2.S1 = Local_R2.S1 - 1;
+  Local_R2.I  = Local_R2.I + 1;
+  Local_R2.S2 = Local_R2.S2 - 1;
+  Local_R2.A1 = Local_R2.A1 % 16;
+  Local_R2.A2 = Local_R2.A2 % 16;
+  Local_R2.A3 = Local_R2.A3 % 16;
+  Local_R2.B  = !Local_R2.B;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/p7.c
===================================================================
--- testsuite/c-c++-common/sso/p7.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/p7.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init7.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.N.C1 = 0xAB0012;
+  Local_R1.N.C2 = 0xCD0034;
+  Local_R1.N.C3 = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.N.C1 = 0xAB0012;
+  Local_R2.N.C2 = 0xCD0034;
+  Local_R2.N.C3 = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = Local_R2.I;
+  Local_R1.N.C1 = Local_R2.N.C1;
+  Local_R1.N.C2 = Local_R2.N.C2;
+  Local_R1.N.C3 = Local_R2.N.C3;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = Local_R1.I;
+  Local_R2.N.C1 = Local_R1.N.C1;
+  Local_R2.N.C2 = Local_R1.N.C2;
+  Local_R2.N.C3 = Local_R1.N.C3;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/r5.c
===================================================================
--- testsuite/c-c++-common/sso/r5.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/r5.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int Get_Elem1 (struct R1 R)
+{
+  struct R1 Tmp = R;
+  return Tmp.A[0];
+}
+
+void Set_Elem1 (struct R1 *R, int I)
+{
+  struct R1 Tmp = *R;
+  Tmp.A[0] = I;
+  *R = Tmp;
+}
+
+int Get_Elem2 (struct R2 R)
+{
+  struct R2 Tmp = R;
+  return Tmp.A[0];
+}
+
+void Set_Elem2 (struct R2 *R, int I)
+{
+  struct R2 Tmp = *R;
+  Tmp.A[0] = I;
+  *R = Tmp;
+}
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  if (Get_Elem1 (A1) != 0xAB0012) abort ();
+
+  Set_Elem1 (&A1, 0xCD0034);
+  if (Get_Elem1 (A1) != 0xCD0034) abort ();
+
+  if (Get_Elem2 (A2) != 0xAB0012) abort ();
+
+  Set_Elem2 (&A2, 0xCD0034);
+  if (Get_Elem2 (A2) != 0xCD0034) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/t3.c
===================================================================
--- testsuite/c-c++-common/sso/t3.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/t3.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,92 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init3.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.S1   = My_R1.S1 - 1;
+  Local_R1.I    = My_R1.I + 1;
+  Local_R1.S2   = My_R1.S2 - 1;
+  Local_R1.N.C1 = My_R1.N.C1 % 16;
+  Local_R1.N.C2 = My_R1.N.C2 % 16;
+  Local_R1.N.C3 = My_R1.N.C3 % 16;
+  Local_R1.N.B  = My_R1.N.B % 2;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 01 7c f3 2a 1e 02 82 01\n" } */
+
+  Local_R2.S1   = My_R2.S1 - 1;
+  Local_R2.I    = My_R2.I + 1;
+  Local_R2.S2   = My_R2.S2 - 1;
+  Local_R2.N.C1 = My_R2.N.C1 % 16;
+  Local_R2.N.C2 = My_R2.N.C2 % 16;
+  Local_R2.N.C3 = My_R2.N.C3 % 16;
+  Local_R2.N.B  = My_R2.N.B % 2;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 05 e2 af 37 c0 04 10 30\n" } */
+
+  Local_R1.S1   = 2;
+  Local_R1.I    = 0x78ABCDEF;
+  Local_R1.S2   = 1;
+  Local_R1.N.C1 = 0x12;
+  Local_R1.N.C2 = 0x34;
+  Local_R1.N.C3 = 0x56;
+  Local_R1.N.B  = 4;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  Local_R2.S1   = 2;
+  Local_R2.I    = 0x78ABCDEF;
+  Local_R2.S2   = 1;
+  Local_R2.N.C1 = 0x12;
+  Local_R2.N.C2 = 0x34;
+  Local_R2.N.C3 = 0x56;
+  Local_R2.N.B  = 4;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  Local_R1.S1   = Local_R1.S1 - 1;
+  Local_R1.I    = Local_R1.I + 1;
+  Local_R1.S2   = Local_R1.S2 - 1;
+  Local_R1.N.C1 = Local_R1.N.C1 % 16;
+  Local_R1.N.C2 = Local_R1.N.C2 % 16;
+  Local_R1.N.C3 = Local_R1.N.C3 % 16;
+  Local_R1.N.B  = Local_R1.N.B % 2;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 01 7c f3 2a 1e 02 82 01\n" } */
+
+  Local_R2.S1   = Local_R2.S1 - 1;
+  Local_R2.I    = Local_R2.I + 1;
+  Local_R2.S2   = Local_R2.S2 - 1;
+  Local_R2.N.C1 = Local_R2.N.C1 % 16;
+  Local_R2.N.C2 = Local_R2.N.C2 % 16;
+  Local_R2.N.C3 = Local_R2.N.C3 % 16;
+  Local_R2.N.B  = Local_R2.N.B % 2;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 05 e2 af 37 c0 04 10 30\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/p8.c
===================================================================
--- testsuite/c-c++-common/sso/p8.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/p8.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init8.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.N.C1 = 0xAB0012;
+  Local_R1.N.C2 = 0xCD0034;
+  Local_R1.N.C3 = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.N.C1 = 0xAB0012;
+  Local_R2.N.C2 = 0xCD0034;
+  Local_R2.N.C3 = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I    = Local_R2.I;
+  Local_R1.N.C1 = Local_R2.N.C1;
+  Local_R1.N.C2 = Local_R2.N.C2;
+  Local_R1.N.C3 = Local_R2.N.C3;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I    = Local_R1.I;
+  Local_R2.N.C1 = Local_R1.N.C1;
+  Local_R2.N.C2 = Local_R1.N.C2;
+  Local_R2.N.C3 = Local_R1.N.C3;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/r6.c
===================================================================
--- testsuite/c-c++-common/sso/r6.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/r6.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int Get_Elem1 (struct R1 R)
+{
+  struct R1 Tmp = R;
+  return Tmp.N.A[0];
+}
+
+void Set_Elem1 (struct R1 *R, int I)
+{
+  struct R1 Tmp = *R;
+  Tmp.N.A[0] = I;
+  *R = Tmp;
+}
+
+int Get_Elem2 (struct R2 R)
+{
+  struct R2 Tmp = R;
+  return Tmp.N.A[0];
+}
+
+void Set_Elem2 (struct R2 *R, int I)
+{
+  struct R2 Tmp = *R;
+  Tmp.N.A[0] = I;
+  *R = Tmp;
+}
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  if (Get_Elem1 (A1) != 0xAB0012) abort ();
+
+  Set_Elem1 (&A1, 0xCD0034);
+  if (Get_Elem1 (A1) != 0xCD0034) abort ();
+
+  if (Get_Elem2 (A2) != 0xAB0012) abort ();
+
+  Set_Elem2 (&A2, 0xCD0034);
+  if (Get_Elem2 (A2) != 0xCD0034) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/t4.c
===================================================================
--- testsuite/c-c++-common/sso/t4.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/t4.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init4.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.F = My_R1.F + 1.0f;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : ee 87 84 40\n" } */
+
+  Local_R2.F = My_R2.F + 1.0f;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 84 87 ee\n" } */
+
+  Local_R1.F = Pi;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40\n" } */
+
+  Local_R2.F = Pi;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db\n" } */
+
+  Local_R1.F = Local_R1.F + 1.0f;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : ee 87 84 40\n" } */
+
+  Local_R2.F = Local_R2.F + 1.0f;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 84 87 ee\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/p9.c
===================================================================
--- testsuite/c-c++-common/sso/p9.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/p9.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,64 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init9.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 18 2d 44 54 fb 21 09 40\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 40 09 21 fb 54 44 2d 18\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  Local_R1.F = Pi;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  Local_R2.F = Pi;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  Local_R1.F = Local_R2.F;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  Local_R2.F = Local_R1.F;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/r7.c
===================================================================
--- testsuite/c-c++-common/sso/r7.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/r7.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init7.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int Get_Elem1 (struct R1 R)
+{
+  struct R1 Tmp = R;
+  return Tmp.N.C1;
+}
+
+void Set_Elem1 (struct R1 *R, int I)
+{
+  struct R1 Tmp = *R;
+  Tmp.N.C1 = I;
+  *R = Tmp;
+}
+
+int Get_Elem2 (struct R2 R)
+{
+  struct R2 Tmp = R;
+  return Tmp.N.C1;
+}
+
+void Set_Elem2 (struct R2 *R, int I)
+{
+  struct R2 Tmp = *R;
+  Tmp.N.C1 = I;
+  *R = Tmp;
+}
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  if (Get_Elem1 (A1) != 0xAB0012) abort ();
+
+  Set_Elem1 (&A1, 0xCD0034);
+  if (Get_Elem1 (A1) != 0xCD0034) abort ();
+
+  if (Get_Elem2 (A2) != 0xAB0012) abort ();
+
+  Set_Elem2 (&A2, 0xCD0034);
+  if (Get_Elem2 (A2) != 0xCD0034) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/t5.c
===================================================================
--- testsuite/c-c++-common/sso/t5.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/t5.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.I    = My_R1.I + 1;
+  Local_R1.A[0] = My_R1.A[0] + 1;
+  Local_R1.A[1] = My_R1.A[1] + 1;
+  Local_R1.A[2] = My_R1.A[2] + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R2.I    = My_R2.I + 1;
+  Local_R2.A[0] = My_R2.A[0] + 1;
+  Local_R2.A[1] = My_R2.A[1] + 1;
+  Local_R2.A[2] = My_R2.A[2] + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.A[0] = 0xAB0012;
+  Local_R1.A[1] = 0xCD0034;
+  Local_R1.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.A[0] = 0xAB0012;
+  Local_R2.A[1] = 0xCD0034;
+  Local_R2.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = Local_R1.I + 1;
+  Local_R1.A[0] = Local_R1.A[0] + 1;
+  Local_R1.A[1] = Local_R1.A[1] + 1;
+  Local_R1.A[2] = Local_R1.A[2] + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R2.I    = Local_R2.I + 1;
+  Local_R2.A[0] = Local_R2.A[0] + 1;
+  Local_R2.A[1] = Local_R2.A[1] + 1;
+  Local_R2.A[2] = Local_R2.A[2] + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/init1.h
===================================================================
--- testsuite/c-c++-common/sso/init1.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/init1.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,12 @@
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  int I;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  int I;
+};
+
+struct R1 My_R1 = { 0x12345678 };
+struct R2 My_R2 = { 0x12345678 };
Index: testsuite/c-c++-common/sso/r8.c
===================================================================
--- testsuite/c-c++-common/sso/r8.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/r8.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init8.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int Get_Elem1 (struct R1 R)
+{
+  struct R1 Tmp = R;
+  return Tmp.N.C1;
+}
+
+void Set_Elem1 (struct R1 *R, int I)
+{
+  struct R1 Tmp = *R;
+  Tmp.N.C1 = I;
+  *R = Tmp;
+}
+
+int Get_Elem2 (struct R2 R)
+{
+  struct R2 Tmp = R;
+  return Tmp.N.C1;
+}
+
+void Set_Elem2 (struct R2 *R, int I)
+{
+  struct R2 Tmp = *R;
+  Tmp.N.C1 = I;
+  *R = Tmp;
+}
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  if (Get_Elem1 (A1) != 0xAB0012) abort ();
+
+  Set_Elem1 (&A1, 0xCD0034);
+  if (Get_Elem1 (A1) != 0xCD0034) abort ();
+
+  if (Get_Elem2 (A2) != 0xAB0012) abort ();
+
+  Set_Elem2 (&A2, 0xCD0034);
+  if (Get_Elem2 (A2) != 0xCD0034) abort ();
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/t6.c
===================================================================
--- testsuite/c-c++-common/sso/t6.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/t6.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.I      = My_R1.I + 1;
+  Local_R1.N.A[0] = My_R1.N.A[0] + 1;
+  Local_R1.N.A[1] = My_R1.N.A[1] + 1;
+  Local_R1.N.A[2] = My_R1.N.A[2] + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R2.I      = My_R2.I + 1;
+  Local_R2.N.A[0] = My_R2.N.A[0] + 1;
+  Local_R2.N.A[1] = My_R2.N.A[1] + 1;
+  Local_R2.N.A[2] = My_R2.N.A[2] + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R1.I      = 0x12345678;
+  Local_R1.N.A[0] = 0xAB0012;
+  Local_R1.N.A[1] = 0xCD0034;
+  Local_R1.N.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I      = 0x12345678;
+  Local_R2.N.A[0] = 0xAB0012;
+  Local_R2.N.A[1] = 0xCD0034;
+  Local_R2.N.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I      = Local_R1.I + 1;
+  Local_R1.N.A[0] = Local_R1.N.A[0] + 1;
+  Local_R1.N.A[1] = Local_R1.N.A[1] + 1;
+  Local_R1.N.A[2] = Local_R1.N.A[2] + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R2.I      = Local_R2.I + 1;
+  Local_R2.N.A[0] = Local_R2.N.A[0] + 1;
+  Local_R2.N.A[1] = Local_R2.N.A[1] + 1;
+  Local_R2.N.A[2] = Local_R2.N.A[2] + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/init2.h
===================================================================
--- testsuite/c-c++-common/sso/init2.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/init2.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,24 @@
+struct __attribute__((scalar_storage_order("little-endian"), packed)) R1
+{
+  unsigned S1 : 2;
+  unsigned I  : 32;
+  unsigned S2 : 2;
+  unsigned A1 : 9;
+  unsigned A2 : 9;
+  unsigned A3 : 9;
+  unsigned B  : 1;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"), packed)) R2
+{
+  unsigned S1 : 2;
+  unsigned I  : 32;
+  unsigned S2 : 2;
+  unsigned A1 : 9;
+  unsigned A2 : 9;
+  unsigned A3 : 9;
+  unsigned B  : 1;
+};
+
+struct R1 My_R1 = { 2, 0x12345678, 1, 0xAB, 0xCD, 0xEF, 1 };
+struct R2 My_R2 = { 2, 0x12345678, 1, 0xAB, 0xCD, 0xEF, 1 };
Index: testsuite/c-c++-common/sso/t7.c
===================================================================
--- testsuite/c-c++-common/sso/t7.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/t7.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init7.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.I    = My_R1.I + 1;
+  Local_R1.N.C1 = My_R1.N.C1 + 1;
+  Local_R1.N.C2 = My_R1.N.C2 + 1;
+  Local_R1.N.C3 = My_R1.N.C3 + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R2.I    = My_R2.I + 1;
+  Local_R2.N.C1 = My_R2.N.C1 + 1;
+  Local_R2.N.C2 = My_R2.N.C2 + 1;
+  Local_R2.N.C3 = My_R2.N.C3 + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.N.C1 = 0xAB0012;
+  Local_R1.N.C2 = 0xCD0034;
+  Local_R1.N.C3 = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.N.C1 = 0xAB0012;
+  Local_R2.N.C2 = 0xCD0034;
+  Local_R2.N.C3 = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = Local_R1.I + 1;
+  Local_R1.N.C1 = Local_R1.N.C1 + 1;
+  Local_R1.N.C2 = Local_R1.N.C2 + 1;
+  Local_R1.N.C3 = Local_R1.N.C3 + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R2.I    = Local_R2.I + 1;
+  Local_R2.N.C1 = Local_R2.N.C1 + 1;
+  Local_R2.N.C2 = Local_R2.N.C2 + 1;
+  Local_R2.N.C3 = Local_R2.N.C3 + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/init3.h
===================================================================
--- testsuite/c-c++-common/sso/init3.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/init3.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,34 @@
+struct __attribute__((scalar_storage_order("little-endian"), packed)) Nested1
+{
+  unsigned C1 : 7;
+  unsigned C2 : 7;
+  unsigned C3 : 7;
+  unsigned B  : 3;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"), packed)) R1
+{
+  unsigned S1 : 6;
+  unsigned I  : 32;
+  unsigned S2 : 2;
+  struct Nested1 N;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"), packed)) Nested2
+{
+  unsigned C1 : 7;
+  unsigned C2 : 7;
+  unsigned C3 : 7;
+  unsigned B  : 3;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"), packed)) R2
+{
+  unsigned S1 : 6;
+  unsigned I  : 32;
+  unsigned S2 : 2;
+  struct Nested2 N;
+};
+
+struct R1 My_R1 = { 2, 0x78ABCDEF, 1, { 0x12, 0x34, 0x56, 4 } };
+struct R2 My_R2 = { 2, 0x78ABCDEF, 1, { 0x12, 0x34, 0x56, 4 } };
Index: testsuite/c-c++-common/sso/t8.c
===================================================================
--- testsuite/c-c++-common/sso/t8.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/t8.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init8.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.I    = My_R1.I + 1;
+  Local_R1.N.C1 = My_R1.N.C1 + 1;
+  Local_R1.N.C2 = My_R1.N.C2 + 1;
+  Local_R1.N.C3 = My_R1.N.C3 + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R2.I    = My_R2.I + 1;
+  Local_R2.N.C1 = My_R2.N.C1 + 1;
+  Local_R2.N.C2 = My_R2.N.C2 + 1;
+  Local_R2.N.C3 = My_R2.N.C3 + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.N.C1 = 0xAB0012;
+  Local_R1.N.C2 = 0xCD0034;
+  Local_R1.N.C3 = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.N.C1 = 0xAB0012;
+  Local_R2.N.C2 = 0xCD0034;
+  Local_R2.N.C3 = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I    = Local_R1.I + 1;
+  Local_R1.N.C1 = Local_R1.N.C1 + 1;
+  Local_R1.N.C2 = Local_R1.N.C2 + 1;
+  Local_R1.N.C3 = Local_R1.N.C3 + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R2.I    = Local_R2.I + 1;
+  Local_R2.N.C1 = Local_R2.N.C1 + 1;
+  Local_R2.N.C2 = Local_R2.N.C2 + 1;
+  Local_R2.N.C3 = Local_R2.N.C3 + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/init4.h
===================================================================
--- testsuite/c-c++-common/sso/init4.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/init4.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,14 @@
+#define Pi 3.1415927f
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  float F;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  float F;
+};
+
+struct R1 My_R1 = { Pi };
+struct R2 My_R2 = { Pi };
Index: testsuite/c-c++-common/sso/t9.c
===================================================================
--- testsuite/c-c++-common/sso/t9.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/t9.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init9.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.F = My_R1.F + 1.0;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 8c 16 22 aa fd 90 10 40\n" } */
+
+  Local_R2.F = My_R2.F + 1.0;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 10 90 fd aa 22 16 8c\n" } */
+
+  Local_R1.F = Pi;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  Local_R2.F = Pi;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  Local_R1.F = Local_R1.F + 1.0;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 8c 16 22 aa fd 90 10 40\n" } */
+
+  Local_R2.F = Local_R2.F + 1.0;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 10 90 fd aa 22 16 8c\n" } */
+
+  return 0;
+}
Index: testsuite/c-c++-common/sso/init5.h
===================================================================
--- testsuite/c-c++-common/sso/init5.h	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso/init5.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,14 @@
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  int I;
+  int A[3];
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  int I;
+  int A[3];
+};
+
+struct R1 My_R1 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
+struct R2 My_R2 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
Index: testsuite/c-c++-common/sso-4.c
===================================================================
--- testsuite/c-c++-common/sso-4.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso-4.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,24 @@
+/* Test support of scalar_storage_order attribute */
+
+/* { dg-do compile } */
+
+struct S3
+{
+  struct __attribute__((scalar_storage_order("big-endian"))) S1
+  {
+    int i;
+  } s1;
+};
+
+struct S4
+{
+  struct __attribute__((scalar_storage_order("little-endian"))) S2
+  {
+    int i;
+  } s2;
+};
+
+void incompatible_assign (struct S3 *s3, struct S4 *s4)
+{
+  s3->s1 = s4->s2; /* { dg-error "(incompatible types|no match)" } */
+}
Index: testsuite/c-c++-common/sso-1.c
===================================================================
--- testsuite/c-c++-common/sso-1.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso-1.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,94 @@
+/* Test support of scalar_storage_order attribute */
+
+/* { dg-do compile } */
+
+struct __attribute__((scalar_storage_order("big-endian"))) S1
+{
+  int i;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) S2
+{
+  int i;
+};
+
+struct __attribute__((scalar_storage_order("other"))) S3 { int i; }; /* { dg-error "must be one of .big-endian. or .little-endian." } */
+
+void incompatible_assign (struct S1 *s1, struct S2 *s2)
+{
+  *s1 = *s2; /* { dg-error "(incompatible types|no match)" } */
+}
+
+int *addr1 (int which, struct S1 *s1, struct S2 *s2)
+{
+  return (which == 1 ? &s1->i : &s2->i); /* { dg-error "address of scalar with reverse storage order" } */
+}
+
+struct __attribute__((scalar_storage_order("big-endian"))) S4
+{
+  int a[4];
+  struct S2 s2;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) S5
+{
+  int a[4];
+  struct S1 s1;
+};
+
+void *addr2 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)s4->a : (void *)s5->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr3 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)&s4->a : (void *)&s5->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr4 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)&s4->a[0] : (void *)&s5->a[0]); /* { dg-error "address of scalar with reverse storage order" } */
+}
+
+void *addr5 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)&s4->s2 : (void *) &s5->s1); /* ok */
+}
+
+struct __attribute__((scalar_storage_order("big-endian"))) S6
+{
+  int a[4][2];
+  struct S2 s2[2];
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) S7
+{
+  int a[4][2];
+  struct S1 s1[2];
+};
+
+void *addr6 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)s6->a : (void *)s7->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr7 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->a : (void *)&s7->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr8 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->a[0] : (void *)&s7->a[0]); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr9 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->a[0][0] : (void *)&s7->a[0][0]); /* { dg-error "address of scalar with reverse storage order" } */
+}
+
+void *addr10 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->s2 : (void *)&s7->s1); /* ok */
+}
Index: testsuite/c-c++-common/sso-5.c
===================================================================
--- testsuite/c-c++-common/sso-5.c	(.../trunk/gcc)	(revision 0)
+++ testsuite/c-c++-common/sso-5.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -0,0 +1,72 @@
+/* Test support of scalar_storage_order pragma */
+
+/* { dg-do run } */
+
+#pragma scalar_storage_order /* { dg-warning "missing .big-endian.little-endian.default." } */
+
+#pragma scalar_storage_order big-endian
+
+struct S1
+{
+  int i;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) S2
+{
+  int i;
+};
+
+#pragma scalar_storage_order little-endian
+
+struct S3
+{
+  int i;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) S4
+{
+  int i;
+};
+
+#pragma scalar_storage_order default
+
+struct S5
+{
+  int i;
+};
+
+#pragma scalar_storage_order other /* { dg-warning "expected .big-endian.little-endian.default." } */
+
+struct S1 my_s1 = { 0x12345678 };
+struct S2 my_s2 = { 0x12345678 };
+struct S3 my_s3 = { 0x12345678 };
+struct S4 my_s4 = { 0x12345678 };
+struct S5 my_s5 = { 0x12345678 };
+
+unsigned char big_endian_pattern[4] = { 0x12, 0x34, 0x56, 0x78 };
+unsigned char little_endian_pattern[4] = { 0x78, 0x56, 0x34, 0x12 };
+
+int main (void)
+{
+  if (__builtin_memcmp (&my_s1, &big_endian_pattern, 4) != 0)
+    __builtin_abort ();
+
+  if (__builtin_memcmp (&my_s2, &little_endian_pattern, 4) != 0)
+    __builtin_abort ();
+
+  if (__builtin_memcmp (&my_s3, &little_endian_pattern, 4) != 0)
+    __builtin_abort ();
+
+  if (__builtin_memcmp (&my_s4, &big_endian_pattern, 4) != 0)
+    __builtin_abort ();
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  if (__builtin_memcmp (&my_s5, &little_endian_pattern, 4) != 0)
+    __builtin_abort ();
+#else
+  if (__builtin_memcmp (&my_s5, &big_endian_pattern, 4) != 0)
+    __builtin_abort ();
+#endif
+
+  return 0;
+}

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 5/6] scalar-storage-order merge: rest
  2015-10-06 11:06 ` [patch 5/6] scalar-storage-order merge: rest Eric Botcazou
@ 2015-10-06 11:09   ` Eric Botcazou
  2015-10-13 16:44   ` Jeff Law
  1 sibling, 0 replies; 32+ messages in thread
From: Eric Botcazou @ 2015-10-06 11:09 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 92 bytes --]

> This is the rest of the implementation.

...with the patch this time...

-- 
Eric Botcazou

[-- Attachment #2: sso-rest.diff --]
[-- Type: text/x-patch, Size: 59042 bytes --]

Index: ipa-polymorphic-call.c
===================================================================
--- ipa-polymorphic-call.c	(.../trunk/gcc)	(revision 228112)
+++ ipa-polymorphic-call.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -761,6 +761,7 @@ ipa_polymorphic_call_context::set_by_inv
 						HOST_WIDE_INT off)
 {
   HOST_WIDE_INT offset2, size, max_size;
+  bool reverse;
   tree base;
 
   invalid = false;
@@ -771,7 +772,7 @@ ipa_polymorphic_call_context::set_by_inv
     return false;
 
   cst = TREE_OPERAND (cst, 0);
-  base = get_ref_base_and_extent (cst, &offset2, &size, &max_size);
+  base = get_ref_base_and_extent (cst, &offset2, &size, &max_size, &reverse);
   if (!DECL_P (base) || max_size == -1 || max_size != size)
     return false;
 
@@ -901,8 +902,10 @@ ipa_polymorphic_call_context::ipa_polymo
 	{
 	  HOST_WIDE_INT size, max_size;
 	  HOST_WIDE_INT offset2;
-	  tree base = get_ref_base_and_extent (TREE_OPERAND (base_pointer, 0),
-					       &offset2, &size, &max_size);
+	  bool reverse;
+	  tree base
+	    = get_ref_base_and_extent (TREE_OPERAND (base_pointer, 0),
+				       &offset2, &size, &max_size, &reverse);
 
 	  if (max_size != -1 && max_size == size)
 	    combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base)),
@@ -1170,6 +1173,7 @@ extr_type_from_vtbl_ptr_store (gimple *s
 {
   HOST_WIDE_INT offset, size, max_size;
   tree lhs, rhs, base;
+  bool reverse;
 
   if (!gimple_assign_single_p (stmt))
     return NULL_TREE;
@@ -1188,7 +1192,7 @@ extr_type_from_vtbl_ptr_store (gimple *s
     ;
   else
     {
-      base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
+      base = get_ref_base_and_extent (lhs, &offset, &size, &max_size, &reverse);
       if (DECL_P (tci->instance))
 	{
 	  if (base != tci->instance)
@@ -1377,6 +1381,7 @@ check_stmt_for_type_change (ao_ref *ao A
 	tree op = walk_ssa_copies (gimple_call_arg (stmt, 0));
 	tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
 	HOST_WIDE_INT offset = 0, size, max_size;
+	bool reverse;
 
 	if (dump_file)
 	  {
@@ -1387,8 +1392,8 @@ check_stmt_for_type_change (ao_ref *ao A
 	/* See if THIS parameter seems like instance pointer.  */
 	if (TREE_CODE (op) == ADDR_EXPR)
 	  {
-	    op = get_ref_base_and_extent (TREE_OPERAND (op, 0),
-					  &offset, &size, &max_size);
+	    op = get_ref_base_and_extent (TREE_OPERAND (op, 0), &offset,
+					  &size, &max_size, &reverse);
 	    if (size != max_size || max_size == -1)
 	      {
                 tci->speculative = true;
@@ -1531,6 +1536,7 @@ ipa_polymorphic_call_context::get_dynami
     {
       tree ref = gimple_call_fn (call);
       HOST_WIDE_INT offset2, size, max_size;
+      bool reverse;
 
       if (TREE_CODE (ref) == OBJ_TYPE_REF)
 	{
@@ -1560,8 +1566,9 @@ ipa_polymorphic_call_context::get_dynami
 		  && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref)))
 		{
 		  tree ref_exp = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (ref));
-		  tree base_ref = get_ref_base_and_extent
-				   (ref_exp, &offset2, &size, &max_size);
+		  tree base_ref
+		    = get_ref_base_and_extent (ref_exp, &offset2, &size,
+					       &max_size, &reverse);
 
 		  /* Finally verify that what we found looks like read from
 		     OTR_OBJECT or from INSTANCE with offset OFFSET.  */
Index: ipa-cp.c
===================================================================
--- ipa-cp.c	(.../trunk/gcc)	(revision 228112)
+++ ipa-cp.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -939,7 +939,7 @@ ipa_get_jf_ancestor_result (struct ipa_j
     {
       tree t = TREE_OPERAND (input, 0);
       t = build_ref_for_offset (EXPR_LOCATION (t), t,
-				ipa_get_jf_ancestor_offset (jfunc),
+				ipa_get_jf_ancestor_offset (jfunc), false,
 				ptr_type_node, NULL, false);
       return build_fold_addr_expr (t);
     }
Index: tree-scalar-evolution.c
===================================================================
--- tree-scalar-evolution.c	(.../trunk/gcc)	(revision 228112)
+++ tree-scalar-evolution.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1728,15 +1728,16 @@ interpret_rhs_expr (struct loop *loop, g
         {
 	  machine_mode mode;
 	  HOST_WIDE_INT bitsize, bitpos;
-	  int unsignedp;
+	  int unsignedp, reversep;
 	  int volatilep = 0;
 	  tree base, offset;
 	  tree chrec3;
 	  tree unitpos;
 
 	  base = get_inner_reference (TREE_OPERAND (rhs1, 0),
-				      &bitsize, &bitpos, &offset,
-				      &mode, &unsignedp, &volatilep, false);
+				      &bitsize, &bitpos, &offset, &mode,
+				      &unsignedp, &reversep, &volatilep,
+				      false);
 
 	  if (TREE_CODE (base) == MEM_REF)
 	    {
Index: builtins.c
===================================================================
--- builtins.c	(.../trunk/gcc)	(revision 228112)
+++ builtins.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -286,14 +286,14 @@ get_object_alignment_2 (tree exp, unsign
   HOST_WIDE_INT bitsize, bitpos;
   tree offset;
   machine_mode mode;
-  int unsignedp, volatilep;
+  int unsignedp, reversep, volatilep;
   unsigned int align = BITS_PER_UNIT;
   bool known_alignment = false;
 
   /* Get the innermost object and the constant (bitpos) and possibly
      variable (offset) offset of the access.  */
-  exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
-			     &mode, &unsignedp, &volatilep, true);
+  exp = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode,
+			     &unsignedp, &reversep, &volatilep, true);
 
   /* Extract alignment information from the innermost object and
      possibly adjust bitpos and offset.  */
Index: tree-ssa-sccvn.c
===================================================================
--- tree-ssa-sccvn.c	(.../trunk/gcc)	(revision 228112)
+++ tree-ssa-sccvn.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -709,6 +709,9 @@ vn_reference_eq (const_vn_reference_t co
 	{
 	  if (vro1->opcode == MEM_REF)
 	    deref1 = true;
+	  /* Do not look through a storage order barrier.  */
+	  else if (vro1->opcode == VIEW_CONVERT_EXPR && vro1->reverse)
+	    return false;
 	  if (vro1->off == -1)
 	    break;
 	  off1 += vro1->off;
@@ -717,6 +720,9 @@ vn_reference_eq (const_vn_reference_t co
 	{
 	  if (vro2->opcode == MEM_REF)
 	    deref2 = true;
+	  /* Do not look through a storage order barrier.  */
+	  else if (vro2->opcode == VIEW_CONVERT_EXPR && vro2->reverse)
+	    return false;
 	  if (vro2->off == -1)
 	    break;
 	  off2 += vro2->off;
@@ -820,9 +826,10 @@ copy_reference_ops_from_ref (tree ref, v
 	    temp.off = tree_to_shwi (TREE_OPERAND (ref, 1));
 	  temp.clique = MR_DEPENDENCE_CLIQUE (ref);
 	  temp.base = MR_DEPENDENCE_BASE (ref);
+	  temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
 	  break;
 	case BIT_FIELD_REF:
-	  /* Record bits and position.  */
+	  /* Record bits, position and storage order.  */
 	  temp.op0 = TREE_OPERAND (ref, 1);
 	  temp.op1 = TREE_OPERAND (ref, 2);
 	  if (tree_fits_shwi_p (TREE_OPERAND (ref, 2)))
@@ -831,6 +838,7 @@ copy_reference_ops_from_ref (tree ref, v
 	      if (off % BITS_PER_UNIT == 0)
 		temp.off = off / BITS_PER_UNIT;
 	    }
+	  temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
 	  break;
 	case COMPONENT_REF:
 	  /* The field decl is enough to unambiguously specify the field,
@@ -927,8 +935,11 @@ copy_reference_ops_from_ref (tree ref, v
 	     operand), so we don't have to put anything
 	     for op* as it will be handled by the iteration  */
 	case REALPART_EXPR:
+	  temp.off = 0;
+	  break;
 	case VIEW_CONVERT_EXPR:
 	  temp.off = 0;
+	  temp.reverse = storage_order_barrier_p (ref);
 	  break;
 	case IMAGPART_EXPR:
 	  /* This is only interesting for its constant offset.  */
@@ -1437,6 +1448,21 @@ fully_constant_vn_reference_p (vn_refere
   return NULL_TREE;
 }
 
+/* Return true if OPS contain a storage order barrier.  */
+
+static bool
+contains_storage_order_barrier_p (vec<vn_reference_op_s> ops)
+{
+  vn_reference_op_t op;
+  unsigned i;
+
+  FOR_EACH_VEC_ELT (ops, i, op)
+    if (op->opcode == VIEW_CONVERT_EXPR && op->reverse)
+      return true;
+
+  return false;
+}
+
 /* Transform any SSA_NAME's in a vector of vn_reference_op_s
    structures into their value numbers.  This is done in-place, and
    the vector passed in is returned.  *VALUEIZED_ANYTHING will specify
@@ -1755,7 +1781,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree
       tree ref2 = TREE_OPERAND (gimple_call_arg (def_stmt, 0), 0);
       tree base2;
       HOST_WIDE_INT offset2, size2, maxsize2;
-      base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2);
+      bool reverse;
+      base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2,
+				       &reverse);
       size2 = tree_to_uhwi (gimple_call_arg (def_stmt, 2)) * 8;
       if ((unsigned HOST_WIDE_INT)size2 / 8
 	  == tree_to_uhwi (gimple_call_arg (def_stmt, 2))
@@ -1778,8 +1806,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree
     {
       tree base2;
       HOST_WIDE_INT offset2, size2, maxsize2;
+      bool reverse;
       base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
-				       &offset2, &size2, &maxsize2);
+				       &offset2, &size2, &maxsize2, &reverse);
       if (maxsize2 != -1
 	  && operand_equal_p (base, base2, 0)
 	  && offset2 <= offset
@@ -1799,14 +1828,17 @@ vn_reference_lookup_3 (ao_ref *ref, tree
 	   && maxsize % BITS_PER_UNIT == 0
 	   && offset % BITS_PER_UNIT == 0
 	   && is_gimple_reg_type (vr->type)
+	   && !contains_storage_order_barrier_p (vr->operands)
 	   && gimple_assign_single_p (def_stmt)
 	   && is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)))
     {
       tree base2;
       HOST_WIDE_INT offset2, size2, maxsize2;
+      bool reverse;
       base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
-				       &offset2, &size2, &maxsize2);
-      if (maxsize2 != -1
+				       &offset2, &size2, &maxsize2, &reverse);
+      if (!reverse
+	  && maxsize2 != -1
 	  && maxsize2 == size2
 	  && size2 % BITS_PER_UNIT == 0
 	  && offset2 % BITS_PER_UNIT == 0
@@ -1838,6 +1870,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree
      to access pieces from.  */
   else if (ref->size == maxsize
 	   && is_gimple_reg_type (vr->type)
+	   && !contains_storage_order_barrier_p (vr->operands)
 	   && gimple_assign_single_p (def_stmt)
 	   && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
     {
@@ -1850,10 +1883,13 @@ vn_reference_lookup_3 (ao_ref *ref, tree
 	{
 	  tree base2;
 	  HOST_WIDE_INT offset2, size2, maxsize2, off;
+	  bool reverse;
 	  base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
-					   &offset2, &size2, &maxsize2);
+					   &offset2, &size2, &maxsize2,
+					   &reverse);
 	  off = offset - offset2;
-	  if (maxsize2 != -1
+	  if (!reverse
+	      && maxsize2 != -1
 	      && maxsize2 == size2
 	      && operand_equal_p (base, base2, 0)
 	      && offset2 <= offset
@@ -1902,7 +1938,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree
     {
       tree base2;
       HOST_WIDE_INT maxsize2;
-      int i, j;
+      int i, j, k;
       auto_vec<vn_reference_op_s> rhs;
       vn_reference_op_t vro;
       ao_ref r;
@@ -1962,6 +1998,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree
       if (j != -1)
 	return (void *)-1;
 
+      /* Punt if the additional ops contain a storage order barrier.  */
+      for (k = i; k >= 0; k--)
+	{
+	  vro = &vr->operands[k];
+	  if (vro->opcode == VIEW_CONVERT_EXPR && vro->reverse)
+	    return (void *)-1;
+	}
+
       /* Now re-write REF to be based on the rhs of the assignment.  */
       copy_reference_ops_from_ref (gimple_assign_rhs1 (def_stmt), &rhs);
 
@@ -2036,7 +2080,6 @@ vn_reference_lookup_3 (ao_ref *ref, tree
       vn_reference_op_s op;
       HOST_WIDE_INT at;
 
-
       /* Only handle non-variable, addressable refs.  */
       if (ref->size != maxsize
 	  || offset % BITS_PER_UNIT != 0
Index: tree-ssa-sccvn.h
===================================================================
--- tree-ssa-sccvn.h	(.../trunk/gcc)	(revision 228112)
+++ tree-ssa-sccvn.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -92,6 +92,7 @@ typedef struct vn_reference_op_struct
   tree op0;
   tree op1;
   tree op2;
+  bool reverse;
 } vn_reference_op_s;
 typedef vn_reference_op_s *vn_reference_op_t;
 typedef const vn_reference_op_s *const_vn_reference_op_t;
Index: dbxout.c
===================================================================
--- dbxout.c	(.../trunk/gcc)	(revision 228112)
+++ dbxout.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -2489,11 +2489,11 @@ dbxout_expand_expr (tree expr)
 	machine_mode mode;
 	HOST_WIDE_INT bitsize, bitpos;
 	tree offset, tem;
-	int volatilep = 0, unsignedp = 0;
+	int unsignedp, reversep, volatilep = 0;
 	rtx x;
 
-	tem = get_inner_reference (expr, &bitsize, &bitpos, &offset,
-				   &mode, &unsignedp, &volatilep, true);
+	tem = get_inner_reference (expr, &bitsize, &bitpos, &offset, &mode,
+				   &unsignedp, &reversep, &volatilep, true);
 
 	x = dbxout_expand_expr (tem);
 	if (x == NULL || !MEM_P (x))
Index: tree-ssa-loop-ivopts.c
===================================================================
--- tree-ssa-loop-ivopts.c	(.../trunk/gcc)	(revision 228112)
+++ tree-ssa-loop-ivopts.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1997,10 +1997,27 @@ may_be_nonaddressable_p (tree expr)
 	 target, thus they are always addressable.  */
       return false;
 
+    case MEM_REF:
+      /* Likewise for MEM_REFs, modulo the storage order.  */
+      return REF_REVERSE_STORAGE_ORDER (expr);
+
+    case BIT_FIELD_REF:
+      if (REF_REVERSE_STORAGE_ORDER (expr))
+	return true;
+      return may_be_nonaddressable_p (TREE_OPERAND (expr, 0));
+
     case COMPONENT_REF:
+      if (TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (expr, 0))))
+	return true;
       return DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1))
 	     || may_be_nonaddressable_p (TREE_OPERAND (expr, 0));
 
+    case ARRAY_REF:
+    case ARRAY_RANGE_REF:
+      if (TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (expr, 0))))
+	return true;
+      return may_be_nonaddressable_p (TREE_OPERAND (expr, 0));
+
     case VIEW_CONVERT_EXPR:
       /* This kind of view-conversions may wrap non-addressable objects
 	 and make them look addressable.  After some processing the
@@ -2009,11 +2026,6 @@ may_be_nonaddressable_p (tree expr)
       if (is_gimple_reg (TREE_OPERAND (expr, 0))
 	  || !is_gimple_addressable (TREE_OPERAND (expr, 0)))
 	return true;
-
-      /* ... fall through ... */
-
-    case ARRAY_REF:
-    case ARRAY_RANGE_REF:
       return may_be_nonaddressable_p (TREE_OPERAND (expr, 0));
 
     CASE_CONVERT:
@@ -4320,13 +4332,14 @@ split_address_cost (struct ivopts_data *
   HOST_WIDE_INT bitpos;
   tree toffset;
   machine_mode mode;
-  int unsignedp, volatilep;
+  int unsignedp, reversep, volatilep;
 
   core = get_inner_reference (addr, &bitsize, &bitpos, &toffset, &mode,
-			      &unsignedp, &volatilep, false);
+			      &unsignedp, &reversep, &volatilep, false);
 
   if (toffset != 0
       || bitpos % BITS_PER_UNIT != 0
+      || reversep
       || TREE_CODE (core) != VAR_DECL)
     {
       *symbol_present = false;
Index: tree-ssa-math-opts.c
===================================================================
--- tree-ssa-math-opts.c	(.../trunk/gcc)	(revision 228112)
+++ tree-ssa-math-opts.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -2030,7 +2030,7 @@ find_bswap_or_nop_load (gimple *stmt, tr
      offset from base to compare to other such leaf node.  */
   HOST_WIDE_INT bitsize, bitpos;
   machine_mode mode;
-  int unsignedp, volatilep;
+  int unsignedp, reversep, volatilep;
   tree offset, base_addr;
 
   /* Not prepared to handle PDP endian.  */
@@ -2041,7 +2041,7 @@ find_bswap_or_nop_load (gimple *stmt, tr
     return false;
 
   base_addr = get_inner_reference (ref, &bitsize, &bitpos, &offset, &mode,
-				   &unsignedp, &volatilep, false);
+				   &unsignedp, &reversep, &volatilep, false);
 
   if (TREE_CODE (base_addr) == MEM_REF)
     {
@@ -2080,6 +2080,8 @@ find_bswap_or_nop_load (gimple *stmt, tr
     return false;
   if (bitsize % BITS_PER_UNIT)
     return false;
+  if (reversep)
+    return false;
 
   if (!init_symbolic_number (n, ref))
     return false;
@@ -2528,11 +2530,11 @@ bswap_replace (gimple *cur_stmt, gimple
 	{
 	  HOST_WIDE_INT bitsize, bitpos;
 	  machine_mode mode;
-	  int unsignedp, volatilep;
+	  int unsignedp, reversep, volatilep;
 	  tree offset;
 
 	  get_inner_reference (src, &bitsize, &bitpos, &offset, &mode,
-			       &unsignedp, &volatilep, false);
+			       &unsignedp, &reversep, &volatilep, false);
 	  if (n->range < (unsigned HOST_WIDE_INT) bitsize)
 	    {
 	      load_offset = (bitsize - n->range) / BITS_PER_UNIT;
Index: tree-ssa-alias.c
===================================================================
--- tree-ssa-alias.c	(.../trunk/gcc)	(revision 228112)
+++ tree-ssa-alias.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -557,10 +557,12 @@ ao_ref_init (ao_ref *r, tree ref)
 tree
 ao_ref_base (ao_ref *ref)
 {
+  bool reverse;
+
   if (ref->base)
     return ref->base;
   ref->base = get_ref_base_and_extent (ref->ref, &ref->offset, &ref->size,
-				       &ref->max_size);
+				       &ref->max_size, &reverse);
   return ref->base;
 }
 
@@ -741,9 +743,10 @@ aliasing_component_refs_p (tree ref1,
   else if (same_p == 1)
     {
       HOST_WIDE_INT offadj, sztmp, msztmp;
-      get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp);
+      bool reverse;
+      get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp, &reverse);
       offset2 -= offadj;
-      get_ref_base_and_extent (base1, &offadj, &sztmp, &msztmp);
+      get_ref_base_and_extent (base1, &offadj, &sztmp, &msztmp, &reverse);
       offset1 -= offadj;
       return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
     }
@@ -759,9 +762,10 @@ aliasing_component_refs_p (tree ref1,
   else if (same_p == 1)
     {
       HOST_WIDE_INT offadj, sztmp, msztmp;
-      get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp);
+      bool reverse;
+      get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp, &reverse);
       offset1 -= offadj;
-      get_ref_base_and_extent (base2, &offadj, &sztmp, &msztmp);
+      get_ref_base_and_extent (base2, &offadj, &sztmp, &msztmp, &reverse);
       offset2 -= offadj;
       return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
     }
@@ -2302,7 +2306,9 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *
       if (ref->max_size == -1)
 	return false;
       HOST_WIDE_INT size, offset, max_size, ref_offset = ref->offset;
-      tree base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
+      bool reverse;
+      tree base
+	= get_ref_base_and_extent (lhs, &offset, &size, &max_size, &reverse);
       /* We can get MEM[symbol: sZ, index: D.8862_1] here,
 	 so base == ref->base does not always hold.  */
       if (base != ref->base)
Index: ifcvt.c
===================================================================
--- ifcvt.c	(.../trunk/gcc)	(revision 228112)
+++ ifcvt.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -953,7 +953,7 @@ noce_emit_move_insn (rtx x, rtx y)
 		}
 
 	      gcc_assert (start < (MEM_P (op) ? BITS_PER_UNIT : BITS_PER_WORD));
-	      store_bit_field (op, size, start, 0, 0, GET_MODE (x), y);
+	      store_bit_field (op, size, start, 0, 0, GET_MODE (x), y, false);
 	      return;
 	    }
 
@@ -1008,7 +1008,7 @@ noce_emit_move_insn (rtx x, rtx y)
   outmode = GET_MODE (outer);
   bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT;
   store_bit_field (inner, GET_MODE_BITSIZE (outmode), bitpos,
-		   0, 0, outmode, y);
+		   0, 0, outmode, y, false);
 }
 
 /* Return the CC reg if it is used in COND.  */
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(.../trunk/gcc)	(revision 228112)
+++ dwarf2out.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -5267,9 +5267,10 @@ add_var_loc_to_decl (tree decl, rtx loc_
 	      && TREE_CODE (TREE_OPERAND (realdecl, 0)) == ADDR_EXPR))
 	{
 	  HOST_WIDE_INT maxsize;
-	  tree innerdecl;
-	  innerdecl
-	    = get_ref_base_and_extent (realdecl, &bitpos, &bitsize, &maxsize);
+	  bool reverse;
+	  tree innerdecl
+	    = get_ref_base_and_extent (realdecl, &bitpos, &bitsize, &maxsize,
+				       &reverse);
 	  if (!DECL_P (innerdecl)
 	      || DECL_IGNORED_P (innerdecl)
 	      || TREE_STATIC (innerdecl)
@@ -14443,12 +14444,12 @@ loc_list_for_address_of_addr_expr_of_ind
   tree obj, offset;
   HOST_WIDE_INT bitsize, bitpos, bytepos;
   machine_mode mode;
-  int unsignedp, volatilep = 0;
+  int unsignedp, reversep, volatilep = 0;
   dw_loc_list_ref list_ret = NULL, list_ret1 = NULL;
 
   obj = get_inner_reference (TREE_OPERAND (loc, 0),
 			     &bitsize, &bitpos, &offset, &mode,
-			     &unsignedp, &volatilep, false);
+			     &unsignedp, &reversep, &volatilep, false);
   STRIP_NOPS (obj);
   if (bitpos % BITS_PER_UNIT)
     {
@@ -14777,10 +14778,10 @@ loc_list_from_tree (tree loc, int want_a
 	tree obj, offset;
 	HOST_WIDE_INT bitsize, bitpos, bytepos;
 	machine_mode mode;
-	int unsignedp, volatilep = 0;
+	int unsignedp, reversep, volatilep = 0;
 
 	obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode,
-				   &unsignedp, &volatilep, false);
+				   &unsignedp, &reversep, &volatilep, false);
 
 	gcc_assert (obj != loc);
 
@@ -16080,7 +16081,7 @@ fortran_common (tree decl, HOST_WIDE_INT
   machine_mode mode;
   HOST_WIDE_INT bitsize, bitpos;
   tree offset;
-  int unsignedp, volatilep = 0;
+  int unsignedp, reversep, volatilep = 0;
 
   /* If the decl isn't a VAR_DECL, or if it isn't static, or if
      it does not have a value (the offset into the common area), or if it
@@ -16096,8 +16097,8 @@ fortran_common (tree decl, HOST_WIDE_INT
   if (TREE_CODE (val_expr) != COMPONENT_REF)
     return NULL_TREE;
 
-  cvar = get_inner_reference (val_expr, &bitsize, &bitpos, &offset,
-			      &mode, &unsignedp, &volatilep, true);
+  cvar = get_inner_reference (val_expr, &bitsize, &bitpos, &offset, &mode,
+			      &unsignedp, &reversep, &volatilep, true);
 
   if (cvar == NULL_TREE
       || TREE_CODE (cvar) != VAR_DECL
Index: tsan.c
===================================================================
--- tsan.c	(.../trunk/gcc)	(revision 228112)
+++ tsan.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -126,9 +126,9 @@ instrument_expr (gimple_stmt_iterator gs
   HOST_WIDE_INT bitsize, bitpos;
   tree offset;
   machine_mode mode;
-  int volatilep = 0, unsignedp = 0;
-  base = get_inner_reference (expr, &bitsize, &bitpos, &offset,
-			      &mode, &unsignedp, &volatilep, false);
+  int unsignedp, reversep, volatilep = 0;
+  base = get_inner_reference (expr, &bitsize, &bitpos, &offset, &mode,
+			      &unsignedp, &reversep, &volatilep, false);
 
   /* No need to instrument accesses to decls that don't escape,
      they can't escape to other threads then.  */
Index: asan.c
===================================================================
--- asan.c	(.../trunk/gcc)	(revision 228112)
+++ asan.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1783,9 +1783,9 @@ instrument_derefs (gimple_stmt_iterator
   HOST_WIDE_INT bitsize, bitpos;
   tree offset;
   machine_mode mode;
-  int volatilep = 0, unsignedp = 0;
-  tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset,
-				    &mode, &unsignedp, &volatilep, false);
+  int unsignedp, reversep, volatilep = 0;
+  tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
+				    &unsignedp, &reversep, &volatilep, false);
 
   if (TREE_CODE (t) == COMPONENT_REF
       && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
Index: gimple-ssa-strength-reduction.c
===================================================================
--- gimple-ssa-strength-reduction.c	(.../trunk/gcc)	(revision 228112)
+++ gimple-ssa-strength-reduction.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -985,7 +985,7 @@ slsr_process_ref (gimple *gs)
   tree ref_expr, base, offset, type;
   HOST_WIDE_INT bitsize, bitpos;
   machine_mode mode;
-  int unsignedp, volatilep;
+  int unsignedp, reversep, volatilep;
   slsr_cand_t c;
 
   if (gimple_vdef (gs))
@@ -1000,7 +1000,9 @@ slsr_process_ref (gimple *gs)
     return;
 
   base = get_inner_reference (ref_expr, &bitsize, &bitpos, &offset, &mode,
-			      &unsignedp, &volatilep, false);
+			      &unsignedp, &reversep, &volatilep, false);
+  if (reversep)
+    return;
   widest_int index = bitpos;
 
   if (!restructure_reference (&base, &offset, &index, &type))
Index: tree-data-ref.c
===================================================================
--- tree-data-ref.c	(.../trunk/gcc)	(revision 228112)
+++ tree-data-ref.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -625,11 +625,12 @@ split_constant_offset_1 (tree type, tree
 	tree base, poffset;
 	HOST_WIDE_INT pbitsize, pbitpos;
 	machine_mode pmode;
-	int punsignedp, pvolatilep;
+	int punsignedp, preversep, pvolatilep;
 
 	op0 = TREE_OPERAND (op0, 0);
-	base = get_inner_reference (op0, &pbitsize, &pbitpos, &poffset,
-				    &pmode, &punsignedp, &pvolatilep, false);
+	base
+	  = get_inner_reference (op0, &pbitsize, &pbitpos, &poffset, &pmode,
+				 &punsignedp, &preversep, &pvolatilep, false);
 
 	if (pbitpos % BITS_PER_UNIT != 0)
 	  return false;
@@ -773,7 +774,7 @@ dr_analyze_innermost (struct data_refere
   HOST_WIDE_INT pbitsize, pbitpos;
   tree base, poffset;
   machine_mode pmode;
-  int punsignedp, pvolatilep;
+  int punsignedp, preversep, pvolatilep;
   affine_iv base_iv, offset_iv;
   tree init, dinit, step;
   bool in_loop = (loop && loop->num);
@@ -781,8 +782,8 @@ dr_analyze_innermost (struct data_refere
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "analyze_innermost: ");
 
-  base = get_inner_reference (ref, &pbitsize, &pbitpos, &poffset,
-			      &pmode, &punsignedp, &pvolatilep, false);
+  base = get_inner_reference (ref, &pbitsize, &pbitpos, &poffset, &pmode,
+			      &punsignedp, &preversep, &pvolatilep, false);
   gcc_assert (base != NULL_TREE);
 
   if (pbitpos % BITS_PER_UNIT != 0)
@@ -792,6 +793,13 @@ dr_analyze_innermost (struct data_refere
       return false;
     }
 
+  if (preversep)
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "failed: reverse storage order.\n");
+      return false;
+    }
+
   if (TREE_CODE (base) == MEM_REF)
     {
       if (!integer_zerop (TREE_OPERAND (base, 1)))
Index: tree-affine.c
===================================================================
--- tree-affine.c	(.../trunk/gcc)	(revision 228112)
+++ tree-affine.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -274,7 +274,7 @@ tree_to_aff_combination (tree expr, tree
   tree cst, core, toffset;
   HOST_WIDE_INT bitpos, bitsize;
   machine_mode mode;
-  int unsignedp, volatilep;
+  int unsignedp, reversep, volatilep;
 
   STRIP_NOPS (expr);
 
@@ -331,8 +331,8 @@ tree_to_aff_combination (tree expr, tree
 	  return;
 	}
       core = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize, &bitpos,
-				  &toffset, &mode, &unsignedp, &volatilep,
-				  false);
+				  &toffset, &mode, &unsignedp, &reversep,
+				  &volatilep, false);
       if (bitpos % BITS_PER_UNIT != 0)
 	break;
       aff_combination_const (comb, type, bitpos / BITS_PER_UNIT);
@@ -899,10 +899,10 @@ get_inner_reference_aff (tree ref, aff_t
   HOST_WIDE_INT bitsize, bitpos;
   tree toff;
   machine_mode mode;
-  int uns, vol;
+  int uns, rev, vol;
   aff_tree tmp;
   tree base = get_inner_reference (ref, &bitsize, &bitpos, &toff, &mode,
-				   &uns, &vol, false);
+				   &uns, &rev, &vol, false);
   tree base_addr = build_fold_addr_expr (base);
 
   /* ADDR = &BASE + TOFF + BITPOS / BITS_PER_UNIT.  */
Index: tree-vect-data-refs.c
===================================================================
--- tree-vect-data-refs.c	(.../trunk/gcc)	(revision 228112)
+++ tree-vect-data-refs.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -2999,7 +2999,7 @@ vect_check_gather_scatter (gimple *stmt,
   tree offtype = NULL_TREE;
   tree decl, base, off;
   machine_mode pmode;
-  int punsignedp, pvolatilep;
+  int punsignedp, reversep, pvolatilep = 0;
 
   base = DR_REF (dr);
   /* For masked loads/stores, DR_REF (dr) is an artificial MEM_REF,
@@ -3031,9 +3031,9 @@ vect_check_gather_scatter (gimple *stmt,
      vectorized.  The following code attempts to find such a preexistng
      SSA_NAME OFF and put the loop invariants into a tree BASE
      that can be gimplified before the loop.  */
-  base = get_inner_reference (base, &pbitsize, &pbitpos, &off,
-			      &pmode, &punsignedp, &pvolatilep, false);
-  gcc_assert (base != NULL_TREE && (pbitpos % BITS_PER_UNIT) == 0);
+  base = get_inner_reference (base, &pbitsize, &pbitpos, &off, &pmode,
+			      &punsignedp, &reversep, &pvolatilep, false);
+  gcc_assert (base && (pbitpos % BITS_PER_UNIT) == 0 && !reversep);
 
   if (TREE_CODE (base) == MEM_REF)
     {
@@ -3584,7 +3584,7 @@ again:
 	  HOST_WIDE_INT pbitsize, pbitpos;
 	  tree poffset;
 	  machine_mode pmode;
-	  int punsignedp, pvolatilep;
+	  int punsignedp, preversep, pvolatilep;
 	  affine_iv base_iv, offset_iv;
 	  tree dinit;
 
@@ -3603,7 +3603,8 @@ again:
 	    }
 
 	  outer_base = get_inner_reference (inner_base, &pbitsize, &pbitpos,
-		          &poffset, &pmode, &punsignedp, &pvolatilep, false);
+					    &poffset, &pmode, &punsignedp,
+					    &preversep, &pvolatilep, false);
 	  gcc_assert (outer_base != NULL_TREE);
 
 	  if (pbitpos % BITS_PER_UNIT != 0)
@@ -3614,6 +3615,14 @@ again:
 	      return false;
 	    }
 
+	  if (preversep)
+	    {
+	      if (dump_enabled_p ())
+		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+				 "failed: reverse storage order.\n");
+	      return false;
+	    }
+
 	  outer_base = build_fold_addr_expr (outer_base);
 	  if (!simple_iv (loop, loop_containing_stmt (stmt), outer_base,
                           &base_iv, false))
Index: gimple-fold.c
===================================================================
--- gimple-fold.c	(.../trunk/gcc)	(revision 228112)
+++ gimple-fold.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -792,13 +792,14 @@ gimple_fold_builtin_memory_op (gimple_st
 	      HOST_WIDE_INT src_offset = 0, dest_offset = 0;
 	      HOST_WIDE_INT size = -1;
 	      HOST_WIDE_INT maxsize = -1;
+	      bool reverse;
 
 	      srcvar = TREE_OPERAND (src, 0);
 	      src_base = get_ref_base_and_extent (srcvar, &src_offset,
-						  &size, &maxsize);
+						  &size, &maxsize, &reverse);
 	      destvar = TREE_OPERAND (dest, 0);
 	      dest_base = get_ref_base_and_extent (destvar, &dest_offset,
-						   &size, &maxsize);
+						   &size, &maxsize, &reverse);
 	      if (tree_fits_uhwi_p (len))
 		maxsize = tree_to_uhwi (len);
 	      else
@@ -5184,6 +5185,8 @@ get_base_constructor (tree base, HOST_WI
 		      tree (*valueize)(tree))
 {
   HOST_WIDE_INT bit_offset2, size, max_size;
+  bool reverse;
+
   if (TREE_CODE (base) == MEM_REF)
     {
       if (!integer_zerop (TREE_OPERAND (base, 1)))
@@ -5224,7 +5227,8 @@ get_base_constructor (tree base, HOST_WI
 
     case ARRAY_REF:
     case COMPONENT_REF:
-      base = get_ref_base_and_extent (base, &bit_offset2, &size, &max_size);
+      base = get_ref_base_and_extent (base, &bit_offset2, &size, &max_size,
+				      &reverse);
       if (max_size == -1 || size != max_size)
 	return NULL_TREE;
       *bit_offset +=  bit_offset2;
@@ -5468,6 +5472,7 @@ fold_const_aggregate_ref_1 (tree t, tree
   tree ctor, idx, base;
   HOST_WIDE_INT offset, size, max_size;
   tree tem;
+  bool reverse;
 
   if (TREE_THIS_VOLATILE (t))
     return NULL_TREE;
@@ -5538,7 +5543,7 @@ fold_const_aggregate_ref_1 (tree t, tree
     case BIT_FIELD_REF:
     case TARGET_MEM_REF:
     case MEM_REF:
-      base = get_ref_base_and_extent (t, &offset, &size, &max_size);
+      base = get_ref_base_and_extent (t, &offset, &size, &max_size, &reverse);
       ctor = get_base_constructor (base, &offset, valueize);
 
       /* Empty constructor.  Always fold to 0.  */
Index: cfgexpand.c
===================================================================
--- cfgexpand.c	(.../trunk/gcc)	(revision 228112)
+++ cfgexpand.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -4398,9 +4398,10 @@ expand_debug_expr (tree exp)
 	machine_mode mode1;
 	HOST_WIDE_INT bitsize, bitpos;
 	tree offset;
-	int volatilep = 0;
-	tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
-					&mode1, &unsignedp, &volatilep, false);
+	int reversep, volatilep = 0;
+	tree tem
+	  = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
+				 &unsignedp, &reversep, &volatilep, false);
 	rtx orig_op0;
 
 	if (bitsize == 0)
@@ -4823,9 +4824,10 @@ expand_debug_expr (tree exp)
 	  if (handled_component_p (TREE_OPERAND (exp, 0)))
 	    {
 	      HOST_WIDE_INT bitoffset, bitsize, maxsize;
+	      bool reverse;
 	      tree decl
-		= get_ref_base_and_extent (TREE_OPERAND (exp, 0),
-					   &bitoffset, &bitsize, &maxsize);
+		= get_ref_base_and_extent (TREE_OPERAND (exp, 0), &bitoffset,
+					   &bitsize, &maxsize, &reverse);
 	      if ((TREE_CODE (decl) == VAR_DECL
 		   || TREE_CODE (decl) == PARM_DECL
 		   || TREE_CODE (decl) == RESULT_DECL)
Index: simplify-rtx.c
===================================================================
--- simplify-rtx.c	(.../trunk/gcc)	(revision 228112)
+++ simplify-rtx.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -317,10 +317,11 @@ delegitimize_mem_from_attrs (rtx x)
 	  {
 	    HOST_WIDE_INT bitsize, bitpos;
 	    tree toffset;
-	    int unsignedp, volatilep = 0;
+	    int unsignedp, reversep, volatilep = 0;
 
-	    decl = get_inner_reference (decl, &bitsize, &bitpos, &toffset,
-					&mode, &unsignedp, &volatilep, false);
+	    decl
+	      = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
+				     &unsignedp, &reversep, &volatilep, false);
 	    if (bitsize != GET_MODE_BITSIZE (mode)
 		|| (bitpos % BITS_PER_UNIT)
 		|| (toffset && !tree_fits_shwi_p (toffset)))
Index: tree-ssa-pre.c
===================================================================
--- tree-ssa-pre.c	(.../trunk/gcc)	(revision 228112)
+++ tree-ssa-pre.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -2534,6 +2534,7 @@ create_component_ref_by_pieces_1 (basic_
 	genop = build2 (MEM_REF, currop->type, baseop, offset);
 	MR_DEPENDENCE_CLIQUE (genop) = currop->clique;
 	MR_DEPENDENCE_BASE (genop) = currop->base;
+	REF_REVERSE_STORAGE_ORDER (genop) = currop->reverse;
 	return genop;
       }
 
@@ -2603,7 +2604,9 @@ create_component_ref_by_pieces_1 (basic_
 	  return NULL_TREE;
 	tree op1 = currop->op0;
 	tree op2 = currop->op1;
-	return fold_build3 (BIT_FIELD_REF, currop->type, genop0, op1, op2);
+	tree t = build3 (BIT_FIELD_REF, currop->type, genop0, op1, op2);
+	REF_REVERSE_STORAGE_ORDER (t) = currop->reverse;
+	return fold (t);
       }
 
       /* For array ref vn_reference_op's, operand 1 of the array ref
Index: tree-sra.c
===================================================================
--- tree-sra.c	(.../trunk/gcc)	(revision 228112)
+++ tree-sra.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -190,12 +190,15 @@ struct access
      when grp_to_be_replaced flag is set.  */
   tree replacement_decl;
 
-  /* Is this particular access write access? */
-  unsigned write : 1;
-
   /* Is this access an access to a non-addressable field? */
   unsigned non_addressable : 1;
 
+  /* Is this access made in reverse storage order? */
+  unsigned reverse : 1;
+
+  /* Is this particular access write access? */
+  unsigned write : 1;
+
   /* Is this access currently in the work queue?  */
   unsigned grp_queued : 1;
 
@@ -434,6 +437,8 @@ dump_access (FILE *f, struct access *acc
   print_generic_expr (f, access->expr, 0);
   fprintf (f, ", type = ");
   print_generic_expr (f, access->type, 0);
+  fprintf (f, ", non_addressable = %d, reverse = %d",
+	   access->non_addressable, access->reverse);
   if (grp)
     fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
 	     "grp_assignment_write = %d, grp_scalar_read = %d, "
@@ -850,9 +855,9 @@ create_access (tree expr, gimple *stmt,
   struct access *access;
   HOST_WIDE_INT offset, size, max_size;
   tree base = expr;
-  bool ptr, unscalarizable_region = false;
+  bool reverse, ptr, unscalarizable_region = false;
 
-  base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
+  base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
 
   if (sra_mode == SRA_MODE_EARLY_IPA
       && TREE_CODE (base) == MEM_REF)
@@ -906,6 +911,7 @@ create_access (tree expr, gimple *stmt,
   access->write = write;
   access->grp_unscalarizable_region = unscalarizable_region;
   access->stmt = stmt;
+  access->reverse = reverse;
 
   if (TREE_CODE (expr) == COMPONENT_REF
       && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
@@ -969,7 +975,7 @@ scalarizable_type_p (tree type)
   }
 }
 
-static void scalarize_elem (tree, HOST_WIDE_INT, HOST_WIDE_INT, tree, tree);
+static void scalarize_elem (tree, HOST_WIDE_INT, HOST_WIDE_INT, bool, tree, tree);
 
 /* Create total_scalarization accesses for all scalar fields of a member
    of type DECL_TYPE conforming to scalarizable_type_p.  BASE
@@ -990,8 +996,9 @@ completely_scalarize (tree base, tree de
 	    tree ft = TREE_TYPE (fld);
 	    tree nref = build3 (COMPONENT_REF, ft, ref, fld, NULL_TREE);
 
-	    scalarize_elem (base, pos, tree_to_uhwi (DECL_SIZE (fld)), nref,
-			    ft);
+	    scalarize_elem (base, pos, tree_to_uhwi (DECL_SIZE (fld)),
+			    TYPE_REVERSE_STORAGE_ORDER (decl_type),
+			    nref, ft);
 	  }
       break;
     case ARRAY_TYPE:
@@ -1017,7 +1024,9 @@ completely_scalarize (tree base, tree de
 		tree nref = build4 (ARRAY_REF, elemtype, ref, size_int (idx),
 				    NULL_TREE, NULL_TREE);
 		int el_off = offset + idx * el_size;
-		scalarize_elem (base, el_off, el_size, nref, elemtype);
+		scalarize_elem (base, el_off, el_size,
+				TYPE_REVERSE_STORAGE_ORDER (decl_type),
+				nref, elemtype);
 	      }
 	    while (++idx <= lenp1);
 	  }
@@ -1031,11 +1040,12 @@ completely_scalarize (tree base, tree de
 /* Create total_scalarization accesses for a member of type TYPE, which must
    satisfy either is_gimple_reg_type or scalarizable_type_p.  BASE must be the
    top-most VAR_DECL representing the variable; within that, POS and SIZE locate
-   the member and REF must be the reference expression for it.  */
+   the member, REVERSE gives its torage order. and REF must be the reference
+   expression for it.  */
 
 static void
-scalarize_elem (tree base, HOST_WIDE_INT pos, HOST_WIDE_INT size,
-		 tree ref, tree type)
+scalarize_elem (tree base, HOST_WIDE_INT pos, HOST_WIDE_INT size, bool reverse,
+		tree ref, tree type)
 {
   if (is_gimple_reg_type (type))
   {
@@ -1043,6 +1053,7 @@ scalarize_elem (tree base, HOST_WIDE_INT
     access->expr = ref;
     access->type = type;
     access->grp_total_scalarization = 1;
+    access->reverse = reverse;
     /* Accesses for intraprocedural SRA can have their stmt NULL.  */
   }
   else
@@ -1118,7 +1129,7 @@ build_access_from_expr_1 (tree expr, gim
      and not the result type.  Ada produces such statements.  We are also
      capable of handling the topmost V_C_E but not any of those buried in other
      handled components.  */
-  if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
+  if (TREE_CODE (expr) == VIEW_CONVERT_EXPR && !storage_order_barrier_p (expr))
     expr = TREE_OPERAND (expr, 0);
 
   if (contains_view_convert_expr_p (expr))
@@ -1251,7 +1262,11 @@ build_accesses_from_assign (gimple *stmt
   lacc = build_access_from_expr_1 (lhs, stmt, true);
 
   if (lacc)
-    lacc->grp_assignment_write = 1;
+    {
+      lacc->grp_assignment_write = 1;
+      if (storage_order_barrier_p (rhs))
+	lacc->grp_unscalarizable_region = 1;
+    }
 
   if (racc)
     {
@@ -1259,6 +1274,8 @@ build_accesses_from_assign (gimple *stmt
       if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
 	  && !is_gimple_reg_type (racc->type))
 	bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
+      if (storage_order_barrier_p (lhs))
+	racc->grp_unscalarizable_region = 1;
     }
 
   if (lacc && racc
@@ -1566,17 +1583,15 @@ make_fancy_name (tree expr)
 }
 
 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
-   EXP_TYPE at the given OFFSET.  If BASE is something for which
-   get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
-   to insert new statements either before or below the current one as specified
-   by INSERT_AFTER.  This function is not capable of handling bitfields.
-
-   BASE must be either a declaration or a memory reference that has correct
-   alignment ifformation embeded in it (e.g. a pre-existing one in SRA).  */
+   EXP_TYPE at the given OFFSET and with storage order REVERSE.  If BASE is
+   something for which get_addr_base_and_unit_offset returns NULL, gsi must
+   be non-NULL and is used to insert new statements either before or below
+   the current one as specified by INSERT_AFTER.  This function is not capable
+   of handling bitfields.  */
 
 tree
 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
-		      tree exp_type, gimple_stmt_iterator *gsi,
+		      bool reverse, tree exp_type, gimple_stmt_iterator *gsi,
 		      bool insert_after)
 {
   tree prev_base = base;
@@ -1633,6 +1648,7 @@ build_ref_for_offset (location_t loc, tr
     exp_type = build_aligned_type (exp_type, align);
 
   mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
+  REF_REVERSE_STORAGE_ORDER (mem_ref) = reverse;
   if (TREE_THIS_VOLATILE (prev_base))
     TREE_THIS_VOLATILE (mem_ref) = 1;
   if (TREE_SIDE_EFFECTS (prev_base))
@@ -1659,13 +1675,17 @@ build_ref_for_model (location_t loc, tre
 
       offset -= int_bit_position (fld);
       exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
-      t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
+      t = build_ref_for_offset (loc, base, offset, model->reverse, exp_type,
+				gsi, insert_after);
+      /* The flag will be set on the record type.  */
+      REF_REVERSE_STORAGE_ORDER (t) = 0;
       return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
 			      NULL_TREE);
     }
   else
-    return build_ref_for_offset (loc, base, offset, model->type,
-				 gsi, insert_after);
+    return
+      build_ref_for_offset (loc, base, offset, model->reverse, model->type,
+			    gsi, insert_after);
 }
 
 /* Attempt to build a memory reference that we could but into a gimple
@@ -2322,8 +2342,8 @@ analyze_access_subtree (struct access *r
 		      && (root->size % BITS_PER_UNIT) == 0);
 	  root->type = build_nonstandard_integer_type (root->size,
 						       TYPE_UNSIGNED (rt));
-	  root->expr = build_ref_for_offset (UNKNOWN_LOCATION,
-					     root->base, root->offset,
+	  root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base,
+					     root->offset, root->reverse,
 					     root->type, NULL, false);
 
 	  if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2447,6 +2467,7 @@ create_artificial_child_access (struct a
   access->type = model->type;
   access->grp_write = true;
   access->grp_read = false;
+  access->reverse = model->reverse;
 
   child = &parent->first_child;
   while (*child && (*child)->offset < new_offset)
@@ -2831,6 +2852,7 @@ get_access_for_expr (tree expr)
 {
   HOST_WIDE_INT offset, size, max_size;
   tree base;
+  bool reverse;
 
   /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
      a different size than the size of its argument and we need the latter
@@ -2838,7 +2860,7 @@ get_access_for_expr (tree expr)
   if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
     expr = TREE_OPERAND (expr, 0);
 
-  base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
+  base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
   if (max_size == -1 || !DECL_P (base))
     return NULL;
 
@@ -4471,6 +4493,7 @@ turn_representatives_into_adjustments (v
 	      adj.type = repr->type;
 	      adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
 	      adj.offset = repr->offset;
+	      adj.reverse = repr->reverse;
 	      adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
 			    && (repr->grp_maybe_modified
 				|| repr->grp_not_necessarilly_dereferenced));
@@ -5097,9 +5120,9 @@ ipa_sra_check_caller (struct cgraph_node
 	  tree offset;
 	  HOST_WIDE_INT bitsize, bitpos;
 	  machine_mode mode;
-	  int unsignedp, volatilep = 0;
+	  int unsignedp, reversep, volatilep = 0;
 	  get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
-			       &unsignedp, &volatilep, false);
+			       &unsignedp, &reversep, &volatilep, false);
 	  if (bitpos % BITS_PER_UNIT)
 	    {
 	      iscc->bad_arg_alignment = true;
Index: ubsan.c
===================================================================
--- ubsan.c	(.../trunk/gcc)	(revision 228112)
+++ ubsan.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -1378,9 +1378,9 @@ instrument_bool_enum_load (gimple_stmt_i
   HOST_WIDE_INT bitsize, bitpos;
   tree offset;
   machine_mode mode;
-  int volatilep = 0, unsignedp = 0;
+  int volatilep = 0, reversep, unsignedp = 0;
   tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
-				   &unsignedp, &volatilep, false);
+				   &unsignedp, &reversep, &volatilep, false);
   tree utype = build_nonstandard_integer_type (modebitsize, 1);
 
   if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
@@ -1763,9 +1763,9 @@ instrument_object_size (gimple_stmt_iter
   HOST_WIDE_INT bitsize, bitpos;
   tree offset;
   machine_mode mode;
-  int volatilep = 0, unsignedp = 0;
+  int volatilep = 0, reversep, unsignedp = 0;
   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
-				    &unsignedp, &volatilep, false);
+				    &unsignedp, &reversep, &volatilep, false);
 
   if (bitpos % BITS_PER_UNIT != 0
       || bitsize != size_in_bytes * BITS_PER_UNIT)
Index: ipa-prop.c
===================================================================
--- ipa-prop.c	(.../trunk/gcc)	(revision 228112)
+++ ipa-prop.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -967,7 +967,9 @@ ipa_load_from_parm_agg (struct ipa_func_
 {
   int index;
   HOST_WIDE_INT size, max_size;
-  tree base = get_ref_base_and_extent (op, offset_p, &size, &max_size);
+  bool reverse;
+  tree base
+    = get_ref_base_and_extent (op, offset_p, &size, &max_size, &reverse);
 
   if (max_size == -1 || max_size != size || *offset_p < 0)
     return false;
@@ -1092,6 +1094,7 @@ compute_complex_assign_jump_func (struct
 {
   HOST_WIDE_INT offset, size, max_size;
   tree op1, tc_ssa, base, ssa;
+  bool reverse;
   int index;
 
   op1 = gimple_assign_rhs1 (stmt);
@@ -1139,7 +1142,7 @@ compute_complex_assign_jump_func (struct
   op1 = TREE_OPERAND (op1, 0);
   if (TREE_CODE (TREE_TYPE (op1)) != RECORD_TYPE)
     return;
-  base = get_ref_base_and_extent (op1, &offset, &size, &max_size);
+  base = get_ref_base_and_extent (op1, &offset, &size, &max_size, &reverse);
   if (TREE_CODE (base) != MEM_REF
       /* If this is a varying address, punt.  */
       || max_size == -1
@@ -1175,6 +1178,7 @@ get_ancestor_addr_info (gimple *assign,
 {
   HOST_WIDE_INT size, max_size;
   tree expr, parm, obj;
+  bool reverse;
 
   if (!gimple_assign_single_p (assign))
     return NULL_TREE;
@@ -1184,7 +1188,7 @@ get_ancestor_addr_info (gimple *assign,
     return NULL_TREE;
   expr = TREE_OPERAND (expr, 0);
   obj = expr;
-  expr = get_ref_base_and_extent (expr, offset, &size, &max_size);
+  expr = get_ref_base_and_extent (expr, offset, &size, &max_size, &reverse);
 
   if (TREE_CODE (expr) != MEM_REF
       /* If this is a varying address, punt.  */
@@ -1450,10 +1454,11 @@ determine_locally_known_aggregate_parts
       else if (TREE_CODE (arg) == ADDR_EXPR)
 	{
 	  HOST_WIDE_INT arg_max_size;
+	  bool reverse;
 
 	  arg = TREE_OPERAND (arg, 0);
 	  arg_base = get_ref_base_and_extent (arg, &arg_offset, &arg_size,
-					  &arg_max_size);
+					      &arg_max_size, &reverse);
 	  if (arg_max_size == -1
 	      || arg_max_size != arg_size
 	      || arg_offset < 0)
@@ -1472,13 +1477,14 @@ determine_locally_known_aggregate_parts
   else
     {
       HOST_WIDE_INT arg_max_size;
+      bool reverse;
 
       gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
 
       by_ref = false;
       check_ref = false;
       arg_base = get_ref_base_and_extent (arg, &arg_offset, &arg_size,
-					  &arg_max_size);
+					  &arg_max_size, &reverse);
       if (arg_max_size == -1
 	  || arg_max_size != arg_size
 	  || arg_offset < 0)
@@ -1499,6 +1505,7 @@ determine_locally_known_aggregate_parts
       gimple *stmt = gsi_stmt (gsi);
       HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
       tree lhs, rhs, lhs_base;
+      bool reverse;
 
       if (!stmt_may_clobber_ref_p_1 (stmt, &r))
 	continue;
@@ -1513,7 +1520,7 @@ determine_locally_known_aggregate_parts
 	break;
 
       lhs_base = get_ref_base_and_extent (lhs, &lhs_offset, &lhs_size,
-					  &lhs_max_size);
+					  &lhs_max_size, &reverse);
       if (lhs_max_size == -1
 	  || lhs_max_size != lhs_size)
 	break;
@@ -3982,6 +3989,7 @@ ipa_modify_call_arguments (struct cgraph
 	      base = force_gimple_operand_gsi (&gsi, base,
 					       true, NULL, true, GSI_SAME_STMT);
 	      expr = fold_build2_loc (loc, MEM_REF, type, base, off);
+	      REF_REVERSE_STORAGE_ORDER (expr) = adj->reverse;
 	      /* If expr is not a valid gimple call argument emit
 	         a load into a temporary.  */
 	      if (is_gimple_reg_type (TREE_TYPE (expr)))
@@ -4001,6 +4009,7 @@ ipa_modify_call_arguments (struct cgraph
 	  else
 	    {
 	      expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off);
+	      REF_REVERSE_STORAGE_ORDER (expr) = adj->reverse;
 	      expr = build_fold_addr_expr (expr);
 	      expr = force_gimple_operand_gsi (&gsi, expr,
 					       true, NULL, true, GSI_SAME_STMT);
@@ -4105,7 +4114,10 @@ ipa_modify_expr (tree *expr, bool conver
 
   tree src;
   if (cand->by_ref)
-    src = build_simple_mem_ref (cand->new_decl);
+    {
+      src = build_simple_mem_ref (cand->new_decl);
+      REF_REVERSE_STORAGE_ORDER (src) = cand->reverse;
+    }
   else
     src = cand->new_decl;
 
@@ -4172,7 +4184,9 @@ ipa_get_adjustment_candidate (tree **exp
     }
 
   HOST_WIDE_INT offset, size, max_size;
-  tree base = get_ref_base_and_extent (**expr, &offset, &size, &max_size);
+  bool reverse;
+  tree base
+    = get_ref_base_and_extent (**expr, &offset, &size, &max_size, &reverse);
   if (!base || size == -1 || max_size == -1)
     return NULL;
 
Index: ipa-prop.h
===================================================================
--- ipa-prop.h	(.../trunk/gcc)	(revision 228112)
+++ ipa-prop.h	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -735,6 +735,10 @@ struct ipa_parm_adjustment
      or one about to be removed.  */
   enum ipa_parm_op op;
 
+  /* Storage order of the original parameter (for the cases when the new
+     parameter is a component of an original one).  */
+  unsigned reverse : 1;
+
   /* The parameter is to be passed by reference.  */
   unsigned by_ref : 1;
 };
@@ -772,7 +776,7 @@ ipa_parm_adjustment *ipa_get_adjustment_
 
 
 /* From tree-sra.c:  */
-tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, tree,
+tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, bool, tree,
 			   gimple_stmt_iterator *, bool);
 
 /* In ipa-cp.c  */
Index: tree-ssa-dce.c
===================================================================
--- tree-ssa-dce.c	(.../trunk/gcc)	(revision 228112)
+++ tree-ssa-dce.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -485,8 +485,10 @@ mark_aliased_reaching_defs_necessary_1 (
     {
       tree base, lhs = gimple_get_lhs (def_stmt);
       HOST_WIDE_INT size, offset, max_size;
+      bool reverse;
       ao_ref_base (ref);
-      base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
+      base
+	= get_ref_base_and_extent (lhs, &offset, &size, &max_size, &reverse);
       /* We can get MEM[symbol: sZ, index: D.8862_1] here,
 	 so base == refd->base does not always hold.  */
       if (base == ref->base)
Index: var-tracking.c
===================================================================
--- var-tracking.c	(.../trunk/gcc)	(revision 228112)
+++ var-tracking.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -5105,9 +5105,10 @@ track_expr_p (tree expr, bool need_rtl)
 		  && TREE_CODE (TREE_OPERAND (realdecl, 0)) == ADDR_EXPR))
 	    {
 	      HOST_WIDE_INT bitsize, bitpos, maxsize;
+	      bool reverse;
 	      tree innerdecl
 		= get_ref_base_and_extent (realdecl, &bitpos, &bitsize,
-					   &maxsize);
+					   &maxsize, &reverse);
 	      if (!DECL_P (innerdecl)
 		  || DECL_IGNORED_P (innerdecl)
 		  /* Do not track declarations for parts of tracked parameters
Index: tree-ssa-structalias.c
===================================================================
--- tree-ssa-structalias.c	(.../trunk/gcc)	(revision 228112)
+++ tree-ssa-structalias.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -3170,6 +3170,7 @@ get_constraint_for_component_ref (tree t
   HOST_WIDE_INT bitsize = -1;
   HOST_WIDE_INT bitmaxsize = -1;
   HOST_WIDE_INT bitpos;
+  bool reverse;
   tree forzero;
 
   /* Some people like to do cute things like take the address of
@@ -3191,7 +3192,7 @@ get_constraint_for_component_ref (tree t
       return;
     }
 
-  t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize);
+  t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize, &reverse);
 
   /* Pretend to take the address of the base, we'll take care of
      adding the required subset of sub-fields below.  */
@@ -3617,9 +3618,12 @@ do_structure_copy (tree lhsop, tree rhso
     {
       HOST_WIDE_INT lhssize, lhsmaxsize, lhsoffset;
       HOST_WIDE_INT rhssize, rhsmaxsize, rhsoffset;
+      bool reverse;
       unsigned k = 0;
-      get_ref_base_and_extent (lhsop, &lhsoffset, &lhssize, &lhsmaxsize);
-      get_ref_base_and_extent (rhsop, &rhsoffset, &rhssize, &rhsmaxsize);
+      get_ref_base_and_extent (lhsop, &lhsoffset, &lhssize, &lhsmaxsize,
+			       &reverse);
+      get_ref_base_and_extent (rhsop, &rhsoffset, &rhssize, &rhsmaxsize,
+			       &reverse);
       for (j = 0; lhsc.iterate (j, &lhsp);)
 	{
 	  varinfo_t lhsv, rhsv;
ndex: gimple-laddress.c
===================================================================
--- gimple-laddress.c	(.../trunk/gcc)	(revision 228112)
+++ gimple-laddress.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -102,10 +102,10 @@ pass_laddress::execute (function *fun)
 	  HOST_WIDE_INT bitsize, bitpos;
 	  tree base, offset;
 	  machine_mode mode;
-	  int volatilep = 0, unsignedp = 0;
+	  int volatilep = 0, reversep, unsignedp = 0;
 	  base = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize,
 				      &bitpos, &offset, &mode, &unsignedp,
-				      &volatilep, false);
+				      &reversep, &volatilep, false);
 	  gcc_assert (base != NULL_TREE && (bitpos % BITS_PER_UNIT) == 0);
 	  if (offset != NULL_TREE)
 	    {
Index: config/s390/s390.c
===================================================================
--- config/s390/s390.c	(.../trunk/gcc)	(revision 228112)
+++ config/s390/s390.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -8728,7 +8728,7 @@ s390_output_pool_entry (rtx exp, machine
       gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
 
       REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
-      assemble_real (r, mode, align);
+      assemble_real (r, mode, align, false);
       break;
 
     case MODE_INT:
Index: config/sh/sh.md
===================================================================
--- config/sh/sh.md	(.../trunk/gcc)	(revision 228112)
+++ config/sh/sh.md	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -12392,7 +12392,7 @@ (define_insn "consttable_sf"
     {
       REAL_VALUE_TYPE d;
       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
-      assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
+      assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode), false);
     }
   return "";
 }
@@ -12410,7 +12410,7 @@ (define_insn "consttable_df"
     {
       REAL_VALUE_TYPE d;
       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
-      assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
+      assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode), false);
     }
   return "";
 }
Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c	(.../trunk/gcc)	(revision 228112)
+++ config/arm/arm.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -22644,7 +22644,7 @@ arm_assemble_integer (rtx x, unsigned in
 
             assemble_real
               (rval, GET_MODE_INNER (mode),
-              i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT);
+              i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT, false);
           }
 
       return true;
Index: config/arm/arm.md
===================================================================
--- config/arm/arm.md	(.../trunk/gcc)	(revision 228112)
+++ config/arm/arm.md	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -10857,7 +10857,7 @@ (define_insn "consttable_4"
 	{
 	  REAL_VALUE_TYPE r;
 	  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
-	  assemble_real (r, GET_MODE (x), BITS_PER_WORD);
+	  assemble_real (r, GET_MODE (x), BITS_PER_WORD, false);
 	  break;
 	}
       default:
@@ -10890,7 +10890,7 @@ (define_insn "consttable_8"
         {
           REAL_VALUE_TYPE r;
           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
-          assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
+          assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD, false);
           break;
         }
       default:
@@ -10915,7 +10915,7 @@ (define_insn "consttable_16"
         {
           REAL_VALUE_TYPE r;
           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
-          assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
+          assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD, false);
           break;
         }
       default:
Index: config/mips/mips.md
===================================================================
--- config/mips/mips.md	(.../trunk/gcc)	(revision 228112)
+++ config/mips/mips.md	(.../branches/scalar-storage-order/gcc)	(revision 228133)
@@ -7309,7 +7309,7 @@ (define_insn "consttable_float"
   gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
   assemble_real (d, GET_MODE (operands[0]),
-		 GET_MODE_BITSIZE (GET_MODE (operands[0])));
+		 GET_MODE_BITSIZE (GET_MODE (operands[0])), false);
   return "";
 }
   [(set (attr "length")

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 0/6] scalar-storage-order merge (2)
  2015-10-06 10:57 [patch 0/6] scalar-storage-order merge (2) Eric Botcazou
                   ` (5 preceding siblings ...)
  2015-10-06 11:08 ` [patch 6/6] scalar-storage-order merge: testsuite Eric Botcazou
@ 2015-10-09 11:33 ` Bernd Schmidt
  2015-10-13 17:33   ` Eric Botcazou
  2015-11-08 18:30 ` Eric Botcazou
  7 siblings, 1 reply; 32+ messages in thread
From: Bernd Schmidt @ 2015-10-09 11:33 UTC (permalink / raw)
  To: Eric Botcazou, gcc-patches

On 10/06/2015 12:57 PM, Eric Botcazou wrote:
> this is a repost of the diff of the scalar-storage-order branch vs mainline.
> It contains the fixes suggested by Joseph for the C front-end and the doc,
> fixes for the handling of complex types, the new pragma scalar_storage_order
> and associated -fsso-struct switch for the C family of languages, and the
> adjustment for vector types suggested by Ramana, plus assorted fixes:
>    https://gcc.gnu.org/ml/gcc-patches/2015-07/msg00024.html
>    https://gcc.gnu.org/ml/gcc-patches/2015-07/msg00138.html
>    https://gcc.gnu.org/ml/gcc-patches/2015-07/msg01500.html
>
> See https://gcc.gnu.org/ml/gcc/2015-06/msg00126.html for the proposal.
>
> I have split the diff into 6 pieces, which are interdependent and thus cannot
> be applied independently: 3 for the Ada, C and C++ front-ends, 1 for the bulk
> of the implementation, 1 for the rest and 1 for the testsuite.
>
> It has been bootstrapped/regtested on x86_64-linux and powerpc-linux.

My main question about this series is - how generally useful do you 
expect it to be? I know of some different projects that would like 
bi-endian capability, but it looks like this series implements something 
that is a little too limited to be of use in these cases. It looks like 
it comes with a nontrivial maintenance cost.


Bernd

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 1/6] scalar-storage-order merge: Ada front-end
  2015-10-06 11:01 ` [patch 1/6] scalar-storage-order merge: Ada front-end Eric Botcazou
@ 2015-10-12 22:23   ` Jeff Law
  0 siblings, 0 replies; 32+ messages in thread
From: Jeff Law @ 2015-10-12 22:23 UTC (permalink / raw)
  To: Eric Botcazou, gcc-patches

On 10/06/2015 05:00 AM, Eric Botcazou wrote:
> This is the Ada front-end (in fact mostly gigi) part.
>
> ada/
> 	* freeze.adb (Check_Component_Storage_Order): Skip a record component
> 	if it has Complex_Representation.
> 	(Freeze_Record_Type): If the type has Complex_Representation, skip
> 	the regular treatment of Scalar_Storage_Order attribute and instead
> 	issue a warning if it is present.
> 	* gcc-interface/gigi.h (set_reverse_storage_order_on_pad_type):
> 	Declare.
> 	* gcc-interface/decl.c (gnat_to_gnu_entity) <discrete_type>: Set the
> 	storage order on the enclosing record for a packed array type.
> 	<E_Array_Type>: Set the storage order.
> 	<E_Array_Subtype>: Likewise.
> 	<E_Record_Type>: Likewise.
> 	<E_Record_Subtype>: Likewise.
> 	(gnat_to_gnu_component_type): Set the reverse storage order on a
> 	padded type built for a non-bit-packed array.
> 	(gnat_to_gnu_field): Likewise.
> 	(components_to_record): Deal with TYPE_REVERSE_STORAGE_ORDER.
> 	* gcc-interface/utils.c (make_packable_type): Likewise.
> 	(pad_type_hasher::equal): Likewise.
> 	(gnat_types_compatible_p): Likewise.
> 	(unchecked_convert): Likewise.
> 	(set_reverse_storage_order_on_pad_type): New public function.
> 	* gcc-interface/trans.c (Attribute_to_gnu): Adjust call to
> 	get_inner_reference.
> 	* gcc-interface/utils2.c (build_unary_op): Likewise.
> 	(gnat_build_constructor): Deal with TYPE_REVERSE_STORAGE_ORDER.
> 	(gnat_rewrite_reference): Propagate REF_REVERSE_STORAGE_ORDER.
FWIW, I consider all the bits referenced above as self-approvable.

jeff

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 6/6] scalar-storage-order merge: testsuite
  2015-10-06 11:08 ` [patch 6/6] scalar-storage-order merge: testsuite Eric Botcazou
@ 2015-10-12 22:26   ` Jeff Law
  0 siblings, 0 replies; 32+ messages in thread
From: Jeff Law @ 2015-10-12 22:26 UTC (permalink / raw)
  To: Eric Botcazou, gcc-patches

On 10/06/2015 05:07 AM, Eric Botcazou wrote:
> This is the testsuite part.
>
> testsuite/
> 	* c-c++-common/sso-1.c: New test.
> 	* c-c++-common/sso-2.c: Likewise.
> 	* c-c++-common/sso-3.c: Likewise.
> 	* c-c++-common/sso-4.c: Likewise.
> 	* c-c++-common/sso-5.c: Likewise.
> 	* c-c++-common/sso-6.c: Likewise.
> 	* c-c++-common/sso-7.c: Likewise.
>          * c-c++-common/sso: New directory.
>          * gcc.dg/sso-1.c: New test.
>          * g++.dg/sso-1.C: Likewise.
>          * gcc.dg/sso: New directory.
>          * g++.dg/sso: Likewise.
> 	* gcc.target/i386/movbe-3.c: New test.
>          * gnat.dg/sso1.adb: New test.
>          * gnat.dg/sso2.ad[sb]: Likewise.
>          * gnat.dg/sso3.adb: Likewise.
>          * gnat.dg/sso4.adb: Likewise.
>          * gnat.dg/sso5.adb: Likewise.
>          * gnat.dg/sso6.adb: Likewise.
>          * gnat.dg/sso7.adb: Likewise.
>          * gnat.dg/specs/sso1.ads: Likewise.
>          * gnat.dg/specs/sso2.ads: Likewise.
>          * gnat.dg/sso: New directory.
And this is OK once the prerequisites have gone in.

Jeff

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 3/6] scalar-storage-order merge: C++ front-end
  2015-10-06 11:03 ` [patch 3/6] scalar-storage-order merge: C++ front-end Eric Botcazou
@ 2015-10-12 22:27   ` Jeff Law
  0 siblings, 0 replies; 32+ messages in thread
From: Jeff Law @ 2015-10-12 22:27 UTC (permalink / raw)
  To: Eric Botcazou, gcc-patches

On 10/06/2015 05:03 AM, Eric Botcazou wrote:
> This is the C++ front-end part, probably incomplete but passes the testsuite.
>
> cp/
> 	* class.c: Add c-family/c-pragma.h.
> 	(finish_struct_1): If structure has reverse scalar storage order,
> 	rewrite the type of array fields with scalar component.  Call
> 	maybe_apply_pragma_scalar_storage_order on entry.
> 	* constexpr.c (reduced_constant_expression_p): Unfold recursion and
> 	deal with TYPE_REVERSE_STORAGE_ORDER.
> 	* typeck.c (structural_comptypes): Return false if two aggregate
> 	types have different scalar storage order.
> 	(cp_build_addr_expr_1) <case COMPONENT_REF>: New case.  Issue the
> 	error for bit-fields here and not later.
> 	<case ARRAY_REF>: Issue error and warning for reverse scalar storage
> 	order.
> 	* typeck2.c (split_nonconstant_init_1) <RECORD_TYPE>: Adjust call to
> 	initializer_constant_valid_p.
Explicitly leaving for Jason.

jeff

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 2/6] scalar-storage-order merge: C front-end
  2015-10-06 11:02 ` [patch 2/6] scalar-storage-order merge: C front-end Eric Botcazou
@ 2015-10-13 11:32   ` Jeff Law
  2015-10-19  8:50     ` Eric Botcazou
  2015-10-28 16:48   ` Joseph Myers
  1 sibling, 1 reply; 32+ messages in thread
From: Jeff Law @ 2015-10-13 11:32 UTC (permalink / raw)
  To: Eric Botcazou, gcc-patches

On 10/06/2015 05:02 AM, Eric Botcazou wrote:
> This is the C front-end + C family part.
>
> 	* doc/extend.texi (type attributes): Document scalar_storage_order.
> 	(Structure-Packing Pragmas): Rename into...
> 	(Structure-Layout Pragmas): ...this.  Document scalar_storage_order.
> 	* doc/invoke.texi (C Dialect Options): Document -fsso-struct
> 	(Warnings): Document -Wno-scalar-storage-order.
> 	* flag-types.h (enum scalar_storage_order_kind): New enumeration.
> c-family/
> 	* c-common.c (c_common_attributes): Add scalar_storage_order.
> 	(handle_scalar_storage_order_attribute): New function.
> 	* c-pragma.c (global_sso): New variable.
> 	(maybe_apply_pragma_scalar_storage_order): New function.
> 	(handle_pragma_scalar_storage_order): Likewise.
> 	(init_pragma): Register scalar_storage_order.
> 	* c-pragma.h (maybe_apply_pragma_scalar_storage_order): Declare.
> 	* c.opt (Wscalar-storage-order): New warning.
> 	(fsso-struct=): New option.
> c/
> 	* c-decl.c (finish_struct): If the structure has reverse storage
> 	order, rewrite the type of array fields with scalar component.  Call
> 	maybe_apply_pragma_scalar_storage_order on entry.
> 	* c-typeck.c (build_unary_op) <ADDR_EXPR>: Remove left-overs.  Issue
> 	errors on bit-fields and reverse SSO here and not...
> 	(c_mark_addressable): ...here.
> 	(output_init_element): Adjust call to initializer_constant_valid_p.
> 	(c_build_qualified_type): Propagate TYPE_REVERSE_STORAGE_ORDER.
>
>   doc/extend.texi     |   69 ++++++++++++++++++++++++++++++++++++++++++--------
>   doc/invoke.texi     |   22 +++++++++++++++-
>   flag-types.h        |    9 +++++-
>   c-family/c.opt      |   17 ++++++++++++
>   c-family/c-common.c |   47 ++++++++++++++++++++++++++++++++++-
>   c-family/c-pragma.c |   50 +++++++++++++++++++++++++++++++++++++
>   c-family/c-pragma.h |    1
>   c/c-typeck.c        |   66 ++++++++++++++++++++++++++++++++++---------------
>   c/c-decl.c          |   48 +++++++++++++++++++++++++-----------
>   8 files changed, 273 insertions(+), 47 deletions(-)
>
> -- Eric Botcazou
>
>
> sso-c.diff
>
>
> Index: doc/extend.texi
> ===================================================================
> --- doc/extend.texi	(.../trunk/gcc)	(revision 228112)
> +++ doc/extend.texi	(.../branches/scalar-storage-order/gcc)	(revision 228133)
> @@ -6310,6 +6310,42 @@ of the structure or union is placed to m
> +@itemize
> +@item Taking the address of a scalar field of a @code{union} or a
> +@code{struct} with reverse scalar storage order is not permitted and will
> +yield an error
Seems reasonable.  Certainly avoids a host of problems tracking this 
stuff later I bet.


> +static tree
> +handle_scalar_storage_order_attribute (tree *node, tree name, tree args,
> +				       int flags, bool *no_add_attrs)
> +{
> +  tree id = TREE_VALUE (args);
> +  tree type;
> +
> +  if (TREE_CODE (*node) == TYPE_DECL
> +      && ! (flags & ATTR_FLAG_CXX11))
> +    node = &TREE_TYPE (*node);
> +  type = *node;
> +
> +  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
> +    error ("scalar_storage_order is not supported");
You might want to consider indicating why it's not supported.  Not that 
I expect folks to be using this on a pdp11 :-)



> Index: c/c-typeck.c
> ===================================================================
> --- c/c-typeck.c	(.../trunk/gcc)	(revision 228112)
> +++ c/c-typeck.c	(.../branches/scalar-storage-order/gcc)	(revision 228133)
> @@ -4173,18 +4173,10 @@ build_unary_op (location_t location,
>   	  goto return_build_unary_op;
>   	}
>
> -      /* For &x[y], return x+y */
> -      if (TREE_CODE (arg) == ARRAY_REF)
> -	{
> -	  tree op0 = TREE_OPERAND (arg, 0);
> -	  if (!c_mark_addressable (op0))
> -	    return error_mark_node;
> -	}
Do we still get a proper diagnostic for &x[y] where x isn't something we 
can mark addressable?

Our testsuites aren't particularly good (IMHO) at ensuring we're getting 
diags in all the cases where they're required.

No real objections, assuming that &x[y] diagnostics is still handled 
correctly somewhere.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 4/6] scalar-storage-order merge: bulk
  2015-10-06 11:05 ` [patch 4/6] scalar-storage-order merge: bulk Eric Botcazou
@ 2015-10-13 16:07   ` Jeff Law
  2015-10-20 16:35     ` Eric Botcazou
  0 siblings, 1 reply; 32+ messages in thread
From: Jeff Law @ 2015-10-13 16:07 UTC (permalink / raw)
  To: Eric Botcazou, gcc-patches

On 10/06/2015 05:04 AM, Eric Botcazou wrote:
> This is the bulk of the implementation.
>
> 	* calls.c (store_unaligned_arguments_into_pseudos): Adjust calls to
> 	extract_bit_field and store_bit_field.
> 	(initialize_argument_information): Adjust call to store_expr.
> 	(load_register_parameters): Adjust call to extract_bit_field.
> 	* expmed.c (check_reverse_storage_order_support): New function.
> 	(check_reverse_float_storage_order_support): Likewise.
> 	(flip_storage_order): Likewise.
> 	(store_bit_field_1): Add REVERSE parameter.  Flip the storage order
> 	of the value if it is true.  Pass REVERSE to recursive call after
> 	adjusting the target offset.
> 	Do not use extraction or movstrict instruction if REVERSE is true.
> 	Pass REVERSE to store_fixed_bit_field.
> 	(store_bit_field): Add REVERSE parameter and pass to it to above.
> 	(store_fixed_bit_field): Add REVERSE parameter and pass to it to
> 	store_split_bit_field and store_fixed_bit_field_1.
> 	(store_fixed_bit_field_1):  Add REVERSE parameter.  Flip the storage
> 	order of the value if it is true and adjust the target offset.
> 	(store_split_bit_field): Add REVERSE parameter and pass it to
> 	store_fixed_bit_field.  Adjust the target offset if it is true.
> 	(extract_bit_field_1): Add REVERSE parameter.  Flip the storage order
> 	of the value if it is true.  Pass REVERSE to recursive call after
> 	adjusting the target offset.
> 	Do not use extraction or subreg instruction if REVERSE is true.
> 	Pass REVERSE to extract_fixed_bit_field.
> 	(extract_bit_field): Add REVERSE parameter and pass to it to above.
> 	(extract_fixed_bit_field): Add REVERSE parameter and pass to it to
> 	extract_split_bit_field and extract_fixed_bit_field_1.
> 	(extract_fixed_bit_field_1): Add REVERSE parameter.  Flip the storage
> 	order of the value if it is true and adjust the target offset.
> 	(extract_split_bit_field): Add REVERSE parameter and pass it to
> 	extract_fixed_bit_field.  Adjust the target offset if it is true.
> 	* expmed.h (flip_storage_order): Declare.
> 	(store_bit_field): Adjust prototype.
> 	(extract_bit_field): Likewise.
> 	* expr.c (emit_group_load_1): Adjust calls to extract_bit_field.
> 	(emit_group_store): Adjust call to store_bit_field.
> 	(copy_blkmode_from_reg): Likewise.
> 	(copy_blkmode_to_reg): Likewise.
> 	(write_complex_part): Likewise.
>   	(read_complex_part): Likewise.
> 	(optimize_bitfield_assignment_op): Add REVERSE parameter.  Assert
> 	that it isn't true if the target is a register.
> 	<PLUS_EXPR>: If it is, do not optimize unless bitsize is equal to 1,
> 	and flip the storage order of the value.
> 	<BIT_IOR_EXPR>: Flip the storage order of the value.
> 	(get_bit_range): Adjust call to get_inner_reference.
> 	(expand_assignment): Adjust calls to get_inner_reference, store_expr,
> 	optimize_bitfield_assignment_op and store_field.  Handle MEM_EXPRs
> 	with reverse storage order.
> 	(store_expr_with_bounds): Add REVERSE parameter and pass it to
> 	recursive calls and call to store_bit_field.  Force the value into a
> 	register if it is true and then flip the storage order of the value.
> 	(store_expr): Add REVERSE parameter and pass it to above.
> 	(categorize_ctor_elements_1): Adjust call to
> 	initializer_constant_valid_p.
> 	(store_constructor_field): Add REVERSE parameter and pass it to
> 	recursive calls and call to store_field.
> 	(store_constructor): Add REVERSE parameter and pass it to calls to
> 	store_constructor_field and store_expr.  Set it to true for an
> 	aggregate type with TYPE_REVERSE_STORAGE_ORDER.
> 	(store_field): Add REVERSE parameter and pass it to recursive calls
> 	and calls to store_expr and store_bit_field.  Temporarily flip the
> 	storage order of the value with record type and integral mode and
> 	adjust the shift if it is true.
> 	(get_inner_reference): Add PREVERSEP parameter and set it to true
> 	upon encoutering a reference with reverse storage order.
> 	(expand_expr_addr_expr_1): Adjust call to get_inner_reference.
> 	(expand_constructor): Adjust call to store_constructor.
> 	(expand_expr_real_2) <CASE_CONVERT>: Pass TYPE_REVERSE_STORAGE_ORDER
> 	of the union type to store_expr in the MEM case and assert that it
> 	isn't set in the REG case.  Adjust call to store_field.
> 	(expand_expr_real_1) <MEM_REF>: Handle reverse storage order.
> 	<normal_inner_ref>: Add REVERSEP variable and adjust calls to
> 	get_inner_reference and extract_bit_field. Temporarily flip the
> 	storage order of the value with record type and integral mode and
> 	adjust the shift if it is true.  Flip the storage order of the value
> 	at the end if it is true.
> 	<VIEW_CONVERT_EXPR>: Add REVERSEP variable and adjust call to
> 	get_inner_reference.  Do not fetch an inner reference if it is true.
> 	* expr.h (store_expr_with_bounds): Ajust prototype.
> 	(store_expr): Likewise.
> 	* fold-const.c (make_bit_field_ref): Add REVERSEP parameter and set
> 	REF_REVERSE_STORAGE_ORDER on the reference according to it.
> 	(optimize_bit_field_compare): Deal with reverse storage order.
> 	Adjust calls to get_inner_reference and make_bit_field_ref.
> 	(decode_field_reference): Add PREVERSEP parameter and adjust call to
> 	get_inner_reference.
> 	(fold_truth_andor_1): Deal with reverse storage order.  Adjust calls
> 	to decode_field_reference and make_bit_field_ref.
> 	(fold_unary_loc) <CASE_CONVERT>: Adjust call to get_inner_reference.
> 	<VIEW_CONVERT_EXPR>: Propagate the REF_REVERSE_STORAGE_ORDER flag.
> 	(fold_comparison): Adjust call to get_inner_reference.
> 	(split_address_to_core_and_offset): Adjust call to
> 	get_inner_reference.
> 	* gimple-expr.c (useless_type_conversion_p): Return false for array
> 	types with different TYPE_REVERSE_STORAGE_ORDER flag.
> 	* gimplify.c (gimplify_expr) <MEM_REF>: Propagate the
> 	REF_REVERSE_STORAGE_ORDER flag.
> 	* lto-streamer-out.c (hash_tree): Deal with
> 	TYPE_REVERSE_STORAGE_ORDER.
> 	* output.h (assemble_real): Adjust prototype.
> 	* print-tree.c (print_node): Convey TYPE_REVERSE_STORAGE_ORDER.
> 	* stor-layout.c (finish_record_layout): Propagate the
> 	TYPE_REVERSE_STORAGE_ORDER flag to the variants.
> 	* tree-core.h (TYPE_REVERSE_STORAGE_ORDER): Document.
> 	(TYPE_SATURATING): Adjust.
> 	(REF_REVERSE_STORAGE_ORDER): Document.
> 	* tree-dfa.c (get_ref_base_and_extent): Add PREVERSE parameter and
> 	set it to true upon encoutering a reference with reverse storage
> 	order.
> 	* tree-dfa.h (get_ref_base_and_extent): Adjust prototype.
> 	* tree-inline.c (remap_gimple_op_r): Propagate the
> 	REF_REVERSE_STORAGE_ORDER flag.
> 	(copy_tree_body_r): Likewise.
> 	* tree-outof-ssa.c (insert_value_copy_on_edge): Adjust call to
> 	store_expr.
> 	* tree-streamer-in.c (unpack_ts_base_value_fields): Deal with
> 	TYPE_REVERSE_STORAGE_ORDER and REF_REVERSE_STORAGE_ORDER.
> 	* tree-streamer-out.c (pack_ts_base_value_fields): Likewise.
> 	* tree.c (stabilize_reference) <BIT_FIELD_REF>: Propagate the
> 	REF_REVERSE_STORAGE_ORDER flag.
> 	(verify_type_variant): Deal with TYPE_REVERSE_STORAGE_ORDER.
> 	(gimple_canonical_types_compatible_p): Likewise.
> 	* tree.h (TYPE_REVERSE_STORAGE_ORDER): New flag.
> 	(TYPE_SATURATING): Adjust.
> 	(REF_REVERSE_STORAGE_ORDER): New flag.
> 	(reverse_storage_order_for_component_p): New inline predicate.
>   	(storage_order_barrier_p): Likewise.
> 	(get_inner_reference): Adjust prototype.
> 	* varasm.c (assemble_real): Add REVERSE parameter.  Flip the storage
> 	order of the value if REVERSE is true.
> 	(compare_constant) <CONSTRUCTOR>: Compare TYPE_REVERSE_STORAGE_ORDER.
> 	(assemble_constant_contents): Adjust call to output_constant.
> 	(output_constant_pool_2): Adjust call to assemble_real.
> 	(initializer_constant_valid_p_1) <CONSTRUCTOR>: Deal with
> 	TYPE_REVERSE_STORAGE_ORDER.
> 	(output_constant): Add REVERSE parameter.
> 	<INTEGER_TYPE>: Flip the storage order of the value if REVERSE is
> 	true.
> 	<REAL_TYPE>: Adjust call to assemble_real.
> 	<COMPLEX_TYPE>: Pass it to recursive calls.
> 	<ARRAY_TYPE>: Likewise.  Adjust call to output_constructor.
> 	<RECORD_TYPE>: Likewise.  Adjust call to output_constructor.
> 	(struct oc_local_state): Add REVERSE field.
> 	(output_constructor_array_range): Adjust calls to output_constant.
> 	(output_constructor_regular_field): Likewise.
> 	(output_constructor_bitfield): Adjust call to output_constructor.
> 	Flip the storage order of the value if REVERSE is true.
> 	(output_constructor): Add REVERSE parameter.  Set it to true for an
> 	aggregate type with TYPE_REVERSE_STORAGE_ORDER.  Adjust call to
> 	output_constructor_bitfield.
> lto/
> 	* lto.c (compare_tree_sccs_1): Deal with TYPE_REVERSE_STORAGE_ORDER.
I must admit, I'm surprised at how many places we compare types in 
ever-so-slightly different ways.  This kind of patch makes that obvious. 
  Not asking you to fix that, just a minor rant.

I suspect there are many comments that we should update as a result of 
this work.  Essentially there's many throughout GCC of the form "On a 
big-endian target" and the like.  With these changes it's more a 
property of the data -- the vast majority of the time the data's 
property is the same as the target, but with this patch it can vary.

I just happened to spot one in varasm.c::output_constructor_bitfield, as 
the comment started shortly after some code this patch changes.  No 
doubt there's others.  I'm torn whether or not to ask you to scan and 
update them.  It's a lot of work and I'm not terribly sure how valuable 
it'll generally be.

Thanks for not trying too hard to optimize this stuff, it makes the 
expmed.c patches (for example) a lot easier to work through :-)

I didn't even try to verify you've got all the paths covered.  I mostly 
tried to make sure the patch didn't break existing code.  I'm going to 
assume that the patch essentially works and that if there's paths 
missing where reversal is needed that you'll take care of them as 
they're exposed.

I'm a bit dismayed at the number of changes to fold-const.c, but 
presumably there's no good way around them.  I probably would have 
looked for a way to punt earlier (that may not be trivial though). 
Given you've done the work, no need to undo it now.

Throughout the code, in cases where you've just added an argument, I've 
assumed you've passed it correctly in the callers -- I largely glossed 
over those with that assumption in mind.

I think this patch is fine.


Jeff

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 5/6] scalar-storage-order merge: rest
  2015-10-06 11:06 ` [patch 5/6] scalar-storage-order merge: rest Eric Botcazou
  2015-10-06 11:09   ` Eric Botcazou
@ 2015-10-13 16:44   ` Jeff Law
  1 sibling, 0 replies; 32+ messages in thread
From: Jeff Law @ 2015-10-13 16:44 UTC (permalink / raw)
  To: Eric Botcazou, gcc-patches

On 10/06/2015 05:05 AM, Eric Botcazou wrote:
> This is the rest of the implementation.
>
> 	* asan.c (instrument_derefs): Adjust call to get_inner_reference.
> 	* builtins.c (get_object_alignment_2): Likewise.
> 	* cfgexpand.c (expand_debug_expr): Adjust call to get_inner_reference
> 	and get_ref_base_and_extent.
> 	* dbxout.c (dbxout_expand_expr): Likewise.
> 	* dwarf2out.c (add_var_loc_to_decl): Likewise.
> 	(loc_list_for_address_of_addr_expr_of_indirect_ref): Likewise.
> 	(loc_list_from_tree): Likewise.
> 	(fortran_common): Likewise.
> 	* gimple-fold.c (gimple_fold_builtin_memory_op): Adjust calls to
> 	get_ref_base_and_extent.
> 	(get_base_constructor): Likewise.
> 	(fold_const_aggregate_ref_1): Likewise.
> 	* gimple-laddress.c (pass_laddress::execute): Adjust call to
> 	get_inner_reference.
> 	* gimple-ssa-strength-reduction.c (slsr_process_ref): Adjust call to
> 	get_inner_reference and bail out on reverse storage order.
> 	* ifcvt.c (noce_emit_move_insn): Adjust calls to store_bit_field.
> 	* ipa-cp.c (ipa_get_jf_ancestor_result): Adjust call to
> 	build_ref_for_offset.
> 	* ipa-polymorphic-call.c (set_by_invariant): Adjust call to
> 	get_ref_base_and_extent.
> 	(ipa_polymorphic_call_context): Likewise.
> 	(extr_type_from_vtbl_ptr_store): Likewise.
> 	(check_stmt_for_type_change): Likewise.
> 	(get_dynamic_type): Likewise.
> 	* ipa-prop.c (ipa_load_from_parm_agg_1): Adjust call to
> 	get_ref_base_and_extent.
> 	(compute_complex_assign_jump_func): Likewise.
> 	(get_ancestor_addr_info): Likewise.
> 	(compute_known_type_jump_func): Likewise.
> 	(determine_known_aggregate_parts): Likewise.
> 	(ipa_get_adjustment_candidate): Likewise.
> 	(ipa_modify_call_arguments): Set REF_REVERSE_STORAGE_ORDER on
> 	MEM_REF.
> 	* ipa-prop.h (ipa_parm_adjustment): Add REVERSE field.
> 	(build_ref_for_offset): Adjust prototype.
> 	* simplify-rtx.c (delegitimize_mem_from_attrs): Adjust call to
> 	get_inner_reference.
> 	* tree-affine.c (tree_to_aff_combination): Adjust call to
> 	get_inner_reference.
> 	(get_inner_reference_aff): Likewise.
> 	* tree-data-ref.c (split_constant_offset_1): Likewise.
> 	(dr_analyze_innermost): Likewise.  Bail out if reverse storage order.
> 	* tree-scalar-evolution.c (interpret_rhs_expr): Adjust call to
> 	get_inner_reference.
> 	* tree-sra.c (struct access): Add REVERSE and move WRITE around.
> 	(dump_access): Print new fields.
> 	(create_access): Adjust call to get_ref_base_and_extent and set the
> 	REVERSE flag according to the result.
> 	(completely_scalarize_record): Set the REVERSE flag.
> 	(scalarize_elem): Add REVERSE parameter.
> 	(build_access_from_expr_1): Preserve storage order barriers.
> 	(build_accesses_from_assign): Likewise.
> 	(build_ref_for_offset): Add REVERSE parameter and set the
> 	REF_REVERSE_STORAGE_ORDER flag accordingly.
> 	(build_ref_for_model): Adjust call to build_ref_for_offset and clear
> 	the REF_REVERSE_STORAGE_ORDER flag if there are components.
> 	(analyze_access_subtree): Likewise.
> 	(create_artificial_child_access): Set the REVERSE flag.
> 	(get_access_for_expr): Adjust call to get_ref_base_and_extent.
> 	(turn_representatives_into_adjustments): Propagate REVERSE flag.
> 	(ipa_sra_check_caller): Adjust call to get_inner_reference.
> 	* tree-ssa-alias.c (ao_ref_base): Adjust call to
> 	get_ref_base_and_extent.
> 	(aliasing_component_refs_p): Likewise.
> 	(stmt_kills_ref_p_1): Likewise.
> 	* tree-ssa-dce.c (mark_aliased_reaching_defs_necessary_1): Likewise.
> 	* tree-ssa-loop-ivopts.c (may_be_nonaddressable_p) <MEM_REF>: New.
> 	Return true if reverse storage order.
> 	<BIT_FIELD_REF>: Likewise.
> 	<COMPONENT_REF>: Likewise.
> 	<ARRAY_REF>: Likewise.
> 	<ARRAY_RANGE_REF>: Likewise.
> 	(split_address_cost): Likewise.  Bail out if reverse storage order.
> 	* tree-ssa-math-opts.c (find_bswap_or_nop_load): Adjust call to
> 	get_inner_reference.  Bail out if reverse storage order.
> 	(bswap_replace): Adjust call to get_inner_reference.
> 	* tree-ssa-pre.c (create_component_ref_by_pieces_1) <MEM_REF>: Set
> 	the REF_REVERSE_STORAGE_ORDER flag.
> 	<BIT_FIELD_REF>: Likewise.
> 	* tree-ssa-sccvn.c (vn_reference_eq): Return false on storage order
> 	barriers.
> 	(copy_reference_ops_from_ref) <MEM_REF>: Set REVERSE field according
>   	to the REF_REVERSE_STORAGE_ORDER flag.
> 	<BIT_FIELD_REF>: Likewise.
> 	<VIEW_CONVERT_EXPR>: Set it for storage order barriers.
> 	(contains_storage_order_barrier_p): New predicate.
> 	(vn_reference_lookup_3): Adjust calls to get_ref_base_and_extent.
> 	Punt on storage order barriers if necessary.
> 	* tree-ssa-sccvn.h (struct vn_reference_op_struct): Add REVERSE.
> 	* tree-ssa-structalias.c (get_constraint_for_component_ref): Adjust
> 	call to get_ref_base_and_extent.
> 	(do_structure_copy): Likewise.
> 	* tree-vect-data-refs.c (vect_check_gather): Adjust call to
> 	get_inner_reference.
> 	(vect_analyze_data_refs): Likewise.  Bail out if reverse storage
> 	order.
> 	* tsan.c (instrument_expr): Adjust call to get_inner_reference.
> 	* ubsan.c (instrument_bool_enum_load): Likewise.
> 	(instrument_object_size): Likewise.
> 	* var-tracking.c (track_expr_p): Adjust call to
> 	get_ref_base_and_extent
> 	* config/arm/arm.c (arm_assemble_integer): Adjust call to
> 	assemble_real
> 	* config/arm/arm.md (consttable_4): Likewise.
> 	(consttable_8): Likewise.
> 	(consttable_16): Likewise.
> 	* config/mips/mips.md (consttable_float): Likewise.
> 	* config/s390/s390.c (s390_output_pool_entry): Likewise.
> 	* config/sh/sh.md (consttable_sf): Likewise.
> 	(consttable_df): Likewise.
This is fine.

jeff

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 0/6] scalar-storage-order merge (2)
  2015-10-09 11:33 ` [patch 0/6] scalar-storage-order merge (2) Bernd Schmidt
@ 2015-10-13 17:33   ` Eric Botcazou
  2015-10-14 15:25     ` Trevor Saunders
  0 siblings, 1 reply; 32+ messages in thread
From: Eric Botcazou @ 2015-10-13 17:33 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: gcc-patches

> My main question about this series is - how generally useful do you
> expect it to be? I know of some different projects that would like
> bi-endian capability, but it looks like this series implements something
> that is a little too limited to be of use in these cases.

AdaCore has customers who have been using it for a few years.  With the inline 
pragma and either the configuration pragma (Ada) or the switch (C/C++), you 
can use it without much code rewriting.

> It looks like it comes with a nontrivial maintenance cost.

Nontrivial but manageable IMO and the heavily modified parts (mostly the RTL 
expander) are "cold" these days.  I suspect that less "limited" versions would 
be far more intrusive and less manageable.

Of course I would do the maintenance (I have been doing it for a few years at 
AdaCore), except for the C++ front-end that I don't know at all; that's why 
I'm OK to drop the C++ support for now.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 0/6] scalar-storage-order merge (2)
  2015-10-13 17:33   ` Eric Botcazou
@ 2015-10-14 15:25     ` Trevor Saunders
  2015-10-14 15:33       ` Jeff Law
  0 siblings, 1 reply; 32+ messages in thread
From: Trevor Saunders @ 2015-10-14 15:25 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Bernd Schmidt, gcc-patches

On Tue, Oct 13, 2015 at 07:32:08PM +0200, Eric Botcazou wrote:
> > My main question about this series is - how generally useful do you
> > expect it to be? I know of some different projects that would like
> > bi-endian capability, but it looks like this series implements something
> > that is a little too limited to be of use in these cases.
> 
> AdaCore has customers who have been using it for a few years.  With the inline 
> pragma and either the configuration pragma (Ada) or the switch (C/C++), you 
> can use it without much code rewriting.
> 
> > It looks like it comes with a nontrivial maintenance cost.
> 
> Nontrivial but manageable IMO and the heavily modified parts (mostly the RTL 
> expander) are "cold" these days.  I suspect that less "limited" versions would 
> be far more intrusive and less manageable.
> 
> Of course I would do the maintenance (I have been doing it for a few years at 
> AdaCore), except for the C++ front-end that I don't know at all; that's why 
> I'm OK to drop the C++ support for now.

I haven't looked at the C++ changes, but I tend to think they mat may be
the language where this is the least useful.  I expect it would be
pretty "trivial" to write some wrapper classes that use bswap in
operators so you could say things like struct { uint32_t_be x; }; and
have x stored in big endian.  At which point all you are really missing
is a flag to have all struct members work that way, but rewriting all
struct members of type uint32_t to uint32_t_be should be straight
forward.

trev

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 0/6] scalar-storage-order merge (2)
  2015-10-14 15:25     ` Trevor Saunders
@ 2015-10-14 15:33       ` Jeff Law
  0 siblings, 0 replies; 32+ messages in thread
From: Jeff Law @ 2015-10-14 15:33 UTC (permalink / raw)
  To: Trevor Saunders, Eric Botcazou; +Cc: Bernd Schmidt, gcc-patches

On 10/14/2015 09:25 AM, Trevor Saunders wrote:
>
> I haven't looked at the C++ changes, but I tend to think they mat may be
> the language where this is the least useful.  I expect it would be
> pretty "trivial" to write some wrapper classes that use bswap in
> operators so you could say things like struct { uint32_t_be x; }; and
> have x stored in big endian.  At which point all you are really missing
> is a flag to have all struct members work that way, but rewriting all
> struct members of type uint32_t to uint32_t_be should be straight
> forward.
I've seen this kind of thing come up in other languages, even some not 
covered by ACT's work.    ACT's work does make supporting the extensions 
in those other languages significantly easier.



jeff

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 2/6] scalar-storage-order merge: C front-end
  2015-10-13 11:32   ` Jeff Law
@ 2015-10-19  8:50     ` Eric Botcazou
  0 siblings, 0 replies; 32+ messages in thread
From: Eric Botcazou @ 2015-10-19  8:50 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

> > +  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
> > +    error ("scalar_storage_order is not supported");
> 
> You might want to consider indicating why it's not supported.  Not that
> I expect folks to be using this on a pdp11 :-)

Done, I added "because endianness is not uniform".

> > -      /* For &x[y], return x+y */
> > -      if (TREE_CODE (arg) == ARRAY_REF)
> > -	{
> > -	  tree op0 = TREE_OPERAND (arg, 0);
> > -	  if (!c_mark_addressable (op0))
> > -	    return error_mark_node;
> > -	}
> 
> Do we still get a proper diagnostic for &x[y] where x isn't something we
> can mark addressable?

Yes, c_mark_addressable is invoked on 'arg' later and the function looks into 
the prefix of an ARRAY_REF

> No real objections, assuming that &x[y] diagnostics is still handled
> correctly somewhere.

OK, thanks.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 4/6] scalar-storage-order merge: bulk
  2015-10-13 16:07   ` Jeff Law
@ 2015-10-20 16:35     ` Eric Botcazou
  0 siblings, 0 replies; 32+ messages in thread
From: Eric Botcazou @ 2015-10-20 16:35 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

> I suspect there are many comments that we should update as a result of
> this work.  Essentially there's many throughout GCC of the form "On a
> big-endian target" and the like.  With these changes it's more a
> property of the data -- the vast majority of the time the data's
> property is the same as the target, but with this patch it can vary.
> 
> I just happened to spot one in varasm.c::output_constructor_bitfield, as
> the comment started shortly after some code this patch changes.  No
> doubt there's others.  I'm torn whether or not to ask you to scan and
> update them.  It's a lot of work and I'm not terribly sure how valuable
> it'll generally be.

I have adjusted the output_constructor_bitfield case to "For big-endian data".
The cases in expmed.c have naked "big-endian" or "big-endian case" so are OK.
I have changed 2 sibling cases in expr.c but left the others unchanged since 
they are about calling conventions.  I think that's pretty much it for the 
files that are touched by the patch.

> Thanks for not trying too hard to optimize this stuff, it makes the
> expmed.c patches (for example) a lot easier to work through :-)
> 
> I didn't even try to verify you've got all the paths covered.  I mostly
> tried to make sure the patch didn't break existing code.  I'm going to
> assume that the patch essentially works and that if there's paths
> missing where reversal is needed that you'll take care of them as
> they're exposed.

Yes, the main issue in expr.c & expmed.c is getting all the paths covered.
I have run the compile and execute C torture testsuites with -fsso-struct set 
to big-endian on x86-64 so I'm relatively confident, but that's not a proof.
And one of the design constraints of the implementation was to change nothing 
to the default endianness support, so I'm more confident about the absence of 
breakages (IIRC we didn't get a single PR for a breakage with the AdaCore 
compilers while we did get a few for cases where the data was not reversed).

> I'm a bit dismayed at the number of changes to fold-const.c, but
> presumably there's no good way around them.  I probably would have
> looked for a way to punt earlier (that may not be trivial though).
> Given you've done the work, no need to undo it now.

Yes, that's the bitfield optimization stuff, so it depends on the endianness.
Initially the changes were even more pervasive because I tried to optimize 
e.g. equality comparisons of 2 bitfields with reverse endianness in there.
But this broke the "all accesses to a scalar in memory are done with the same 
storage order" invariant and was thus causing annoying issues later on.

> I think this patch is fine.

OK, thanks for the thorough review.  All the parts have been approved, modulo 
the C++ FE part.  As I already explained, this part is very likely incomplete 
(based on the changes that were made in the Ada FE proper) and only makes sure 
that C code compiled by the C++ compiler works as intended, but nothing more.
So I can propose to install only the generic, C and Ada changes for now and to 
explicitly disable the feature for C++ until a more complete implementation of 
the C++ FE part is written.  I'm OK to work on it but I'll probably need help.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 2/6] scalar-storage-order merge: C front-end
  2015-10-06 11:02 ` [patch 2/6] scalar-storage-order merge: C front-end Eric Botcazou
  2015-10-13 11:32   ` Jeff Law
@ 2015-10-28 16:48   ` Joseph Myers
  2015-10-28 17:32     ` Jeff Law
  2015-10-28 22:34     ` Eric Botcazou
  1 sibling, 2 replies; 32+ messages in thread
From: Joseph Myers @ 2015-10-28 16:48 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

Why is -fsso-struct= listed only for C and C++, not ObjC and ObjC++?  
Almost all C options should be supported for ObjC and almost all C++ 
options should be supported for ObjC++ (and the existing cases that aren't 
in c.opt generally look dubious).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 2/6] scalar-storage-order merge: C front-end
  2015-10-28 16:48   ` Joseph Myers
@ 2015-10-28 17:32     ` Jeff Law
  2015-10-28 22:34     ` Eric Botcazou
  1 sibling, 0 replies; 32+ messages in thread
From: Jeff Law @ 2015-10-28 17:32 UTC (permalink / raw)
  To: Joseph Myers, Eric Botcazou; +Cc: gcc-patches

On 10/28/2015 10:43 AM, Joseph Myers wrote:
> Why is -fsso-struct= listed only for C and C++, not ObjC and ObjC++?
> Almost all C options should be supported for ObjC and almost all C++
> options should be supported for ObjC++ (and the existing cases that aren't
> in c.opt generally look dubious).
I missed it in the review.  However, I think verifying that it works 
with ObjC/C++ should be done prior to adding it though.

jeff

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 2/6] scalar-storage-order merge: C front-end
  2015-10-28 16:48   ` Joseph Myers
  2015-10-28 17:32     ` Jeff Law
@ 2015-10-28 22:34     ` Eric Botcazou
  2015-10-28 23:36       ` Mike Stump
  1 sibling, 1 reply; 32+ messages in thread
From: Eric Botcazou @ 2015-10-28 22:34 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc-patches

> Why is -fsso-struct= listed only for C and C++, not ObjC and ObjC++?

Because it was not tested with the latter 2 languages at all and may require 
specific adjustments in the respective front-ends to work.

> Almost all C options should be supported for ObjC and almost all C++
> options should be supported for ObjC++ (and the existing cases that aren't
> in c.opt generally look dubious).

Sorry, I have zero experience with ObjC and objC++, let alone their front-end.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 2/6] scalar-storage-order merge: C front-end
  2015-10-28 22:34     ` Eric Botcazou
@ 2015-10-28 23:36       ` Mike Stump
  2015-10-29  0:23         ` Joseph Myers
  2015-10-30  8:59         ` Eric Botcazou
  0 siblings, 2 replies; 32+ messages in thread
From: Mike Stump @ 2015-10-28 23:36 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Joseph Myers, gcc-patches

On Oct 28, 2015, at 3:04 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> Why is -fsso-struct= listed only for C and C++, not ObjC and ObjC++?
> 
> Because it was not tested with the latter 2 languages at all and may require 
> specific adjustments in the respective front-ends to work.

It won’t.  Fixing the language line for the options and a make to ensure it still builds for you is enough testing.

>> Almost all C options should be supported for ObjC and almost all C++
>> options should be supported for ObjC++ (and the existing cases that aren't
>> in c.opt generally look dubious).
> 
> Sorry, I have zero experience with ObjC and objC++, let alone their front-end.

None is needed.  One merely copies the string as found on other options for your new options, and you’re done.  Indeed, the default should be to always include the objective languages unless one goes out of their way to exclude them.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 2/6] scalar-storage-order merge: C front-end
  2015-10-28 23:36       ` Mike Stump
@ 2015-10-29  0:23         ` Joseph Myers
  2015-10-30  8:59         ` Eric Botcazou
  1 sibling, 0 replies; 32+ messages in thread
From: Joseph Myers @ 2015-10-29  0:23 UTC (permalink / raw)
  To: Mike Stump; +Cc: Eric Botcazou, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1802 bytes --]

On Wed, 28 Oct 2015, Mike Stump wrote:

> On Oct 28, 2015, at 3:04 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> >> Why is -fsso-struct= listed only for C and C++, not ObjC and ObjC++?
> > 
> > Because it was not tested with the latter 2 languages at all and may require 
> > specific adjustments in the respective front-ends to work.
> 
> It wonÂ’t.  Fixing the language line for the options and a make to ensure 
> it still builds for you is enough testing.

There *can* be cases where one knows that updates would be needed to 
support a new feature for ObjC and ObjC++.  But those are the exception 
rather than the rule and should have a specific comment explaining what 
the issue is and what would need to be done to enable the feature for 
them.  I don't see why that would apply in this case, so I think just 
adding the languages in c.opt should be enough.  (Cf. for C11 _Atomic:

        case RID_ATOMIC:
          /* C parser handling of Objective-C constructs needs
             checking for correct lvalue-to-rvalue conversions, and
             the code in build_modify_expr handling various
             Objective-C cases, and that in build_unary_op handling
             Objective-C cases for increment / decrement, also needs
             updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
             and objc_types_are_equivalent may also need updates.  */
          if (c_dialect_objc ())
            sorry ("%<_Atomic%> in Objective-C");

but no other C11 feature needed any such disabling for ObjC.  [_Atomic has 
similar disabling for OpenMP, again because of parser constructs involving 
lvalue-to-rvalue conversions that would need updating to generate proper 
atomic loads via convert_lvalue_to_rvalue or otherwise.])

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 2/6] scalar-storage-order merge: C front-end
  2015-10-28 23:36       ` Mike Stump
  2015-10-29  0:23         ` Joseph Myers
@ 2015-10-30  8:59         ` Eric Botcazou
  2015-10-30 14:50           ` Mike Stump
  1 sibling, 1 reply; 32+ messages in thread
From: Eric Botcazou @ 2015-10-30  8:59 UTC (permalink / raw)
  To: Mike Stump; +Cc: gcc-patches, Joseph Myers

> It won’t.  Fixing the language line for the options and a make to ensure it
> still builds for you is enough testing.

I was talking about the feature itself though, not about the option per se.  
The feature is tested for C & C++ but not for ObjC & ObjC++ so there might be 
surprises.

> None is needed.  One merely copies the string as found on other options for
> your new options, and you’re done.  Indeed, the default should be to always
> include the objective languages unless one goes out of their way to exclude
> them.

OK, I can enable the option for ObjC & ObjC++ but this comes with no warranty.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 2/6] scalar-storage-order merge: C front-end
  2015-10-30  8:59         ` Eric Botcazou
@ 2015-10-30 14:50           ` Mike Stump
  0 siblings, 0 replies; 32+ messages in thread
From: Mike Stump @ 2015-10-30 14:50 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches, Joseph Myers

On Oct 30, 2015, at 1:56 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> It won’t.  Fixing the language line for the options and a make to ensure it
>> still builds for you is enough testing.
> 
> I was talking about the feature itself though, not about the option per se.  
> The feature is tested for C & C++ but not for ObjC & ObjC++ so there might be 
> surprises.

We welcome such testing, qualification and bug fixing; not a strict requirement on submissions as far as I know.  Some things won’t work well without a concerted effort, and I don’t think it is fair to contributors to require they learn Objective-C/C++ to make such a contribution.  All we generally ask for is that what works today, remain working.  This usually just means leave the existing hooks in and as code moves around, one has to move the hook around.  Whenever a feature conflicts with an Objective feature, I think a nice rule of thumb is that cost is born by the Objective people.  We don’t want to make life any more difficult on anyone else.

> OK, I can enable the option for ObjC & ObjC++ but this comes with no warranty.

Yeah, that’s standard operating procedure.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 0/6] scalar-storage-order merge (2)
  2015-10-06 10:57 [patch 0/6] scalar-storage-order merge (2) Eric Botcazou
                   ` (6 preceding siblings ...)
  2015-10-09 11:33 ` [patch 0/6] scalar-storage-order merge (2) Bernd Schmidt
@ 2015-11-08 18:30 ` Eric Botcazou
  7 siblings, 0 replies; 32+ messages in thread
From: Eric Botcazou @ 2015-11-08 18:30 UTC (permalink / raw)
  To: gcc-patches

> See https://gcc.gnu.org/ml/gcc/2015-06/msg00126.html for the proposal.

The branch has been merged into mainline but without C++ support.  This means 
that the scalar_storage_order attribute is supported in C, Objective-C and Ada 
only for the time being; the branch will remain open to host the C++ support.
I'm also going to submit a small patch to add minimal debug info support.

The result of the merge was bootstrapped/regtested on x86/Linux, x86/Solaris, 
x86-64/Linux, PowerPC/Linux, IA-64/Linux and SPARC/Solaris.

Bugzilla tickets pertaining to the attribute should be tagged with [sso] and 
ebotcazou@gcc.gnu.org be added to the CC field.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 6/6] scalar-storage-order merge: testsuite
  2015-06-18 20:29     ` Eric Botcazou
@ 2015-06-19  9:17       ` Eric Botcazou
  0 siblings, 0 replies; 32+ messages in thread
From: Eric Botcazou @ 2015-06-19  9:17 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: gcc-patches

> > Can I modify an existing struct to create an opposite endian variant?
> > Eg.
> > 
> > struct bar
> > {
> > 
> > 	int a;
> > 
> > };
> > 
> > struct wibble
> > {
> > 
> > 	struct __attr_sso__ bar a;
> > 
> > };
> 
> The compiler accepts it, but apparently discards the attribute silently,
> which looks like a bug to me.  Let me investigate.

This looks like an existing hole, the following is also silently accepted:

struct S1 { int i; };

struct S2 { struct __attribute__((unknown_attribute)) S1 s1; };

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 6/6] scalar-storage-order merge: testsuite
  2015-06-16 13:30   ` Richard Earnshaw
@ 2015-06-18 20:29     ` Eric Botcazou
  2015-06-19  9:17       ` Eric Botcazou
  0 siblings, 1 reply; 32+ messages in thread
From: Eric Botcazou @ 2015-06-18 20:29 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: gcc-patches

> It appears that all the C tests check the specific syntactic form
> 'struct __attr_sso__ foo {...};'
> 
> What is the impact of changing the location of __attr_sso__?  Eg:
> 
> struct foo {...} __attr_sso__;

None.  What impact could it have?

> (Note that alignment attributes can have significant impact depending on
> where in the syntax the attribute is placed (I'm expecting this will be
> true here as well).

Ouch.  This sounds like a bug to me.

> What about with typedefs?

It's ignored (with a warning) on typedefs.

> Can I apply the attribute to a previously laid out struct?

Example?  Is that supported for other type attributes?

> Can I apply it to individual fields in the struct, eg:
> 
> struct bar
> {
> 	int a;
> 	int __attr_sso__ b;
> };

No, but you can do this:

struct bar
{
        int a;
        struct __attr_sso__ foo
        {
          int b;
        } s;
};

> Can I modify an existing struct to create an opposite endian variant? Eg.
> 
> struct bar
> {
> 	int a;
> };
> 
> struct wibble
> {
> 	struct __attr_sso__ bar a;
> };

The compiler accepts it, but apparently discards the attribute silently, which 
looks like a bug to me.  Let me investigate.

> Assuming mixed fields in a struct are possible, can it be applied to
> individual bitfields?  What is the impact on mixing big and little
> endian bitfields in the same structure.

Mixing bitfields with different endianness is simply not possible, they would 
be non-contiguous in one of the orders.  The endianness can only be flipped on 
storage unit boundaries, which is automatically enforced in the C family of 
languages by the aggregate type constraint (but not in Ada, so we have a 
specific check to that effect in the Ada compiler).

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [patch 6/6] scalar-storage-order merge: testsuite
  2015-06-16  9:59 ` [patch 6/6] scalar-storage-order merge: testsuite Eric Botcazou
@ 2015-06-16 13:30   ` Richard Earnshaw
  2015-06-18 20:29     ` Eric Botcazou
  0 siblings, 1 reply; 32+ messages in thread
From: Richard Earnshaw @ 2015-06-16 13:30 UTC (permalink / raw)
  To: Eric Botcazou, gcc-patches

On 16/06/15 10:52, Eric Botcazou wrote:
> This is the testsuite part.
> 
> testsuite/
> 	* c-c++-common/sso-1.c: New test.
> 	* c-c++-common/sso: New directory.
> 	* gcc.dg/sso-1.c: New test.
> 	* g++.dg/sso-1.C: Likewise.
> 	* gcc.dg/sso: New directory.
> 	* g++.dg/sso: Likewise.
> 	* gnat.dg/sso1.adb: New test.
> 	* gnat.dg/sso2.ad[sb]: Likewise.
> 	* gnat.dg/sso3.adb: Likewise.
> 	* gnat.dg/sso4.adb: Likewise.
> 	* gnat.dg/sso5.adb: Likewise.
> 	* gnat.dg/sso6.adb: Likewise.
> 	* gnat.dg/sso7.adb: Likewise.
> 	* gnat.dg/specs/sso1.ads: Likewise.
> 	* gnat.dg/specs/sso2.ads: Likewise.
> 	* gnat.dg/sso: New directory.
> 

It appears that all the C tests check the specific syntactic form
'struct __attr_sso__ foo {...};'

What is the impact of changing the location of __attr_sso__?  Eg:

struct foo {...} __attr_sso__;

(Note that alignment attributes can have significant impact depending on
where in the syntax the attribute is placed (I'm expecting this will be
true here as well).

What about with typedefs?

Can I apply the attribute to a previously laid out struct?

Can I apply it to individual fields in the struct, eg:

struct bar
{
	int a;
	int __attr_sso__ b;
};

Can I modify an existing struct to create an opposite endian variant? Eg.

struct bar
{
	int a;
};

struct wibble
{
	struct __attr_sso__ bar a;
};

Assuming mixed fields in a struct are possible, can it be applied to
individual bitfields?  What is the impact on mixing big and little
endian bitfields in the same structure.

R.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [patch 6/6] scalar-storage-order merge: testsuite
  2015-06-16  8:46 [patch 0/6] scalar-storage-order merge Eric Botcazou
@ 2015-06-16  9:59 ` Eric Botcazou
  2015-06-16 13:30   ` Richard Earnshaw
  0 siblings, 1 reply; 32+ messages in thread
From: Eric Botcazou @ 2015-06-16  9:59 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 7916 bytes --]

This is the testsuite part.

testsuite/
	* c-c++-common/sso-1.c: New test.
	* c-c++-common/sso: New directory.
	* gcc.dg/sso-1.c: New test.
	* g++.dg/sso-1.C: Likewise.
	* gcc.dg/sso: New directory.
	* g++.dg/sso: Likewise.
	* gnat.dg/sso1.adb: New test.
	* gnat.dg/sso2.ad[sb]: Likewise.
	* gnat.dg/sso3.adb: Likewise.
	* gnat.dg/sso4.adb: Likewise.
	* gnat.dg/sso5.adb: Likewise.
	* gnat.dg/sso6.adb: Likewise.
	* gnat.dg/sso7.adb: Likewise.
	* gnat.dg/specs/sso1.ads: Likewise.
	* gnat.dg/specs/sso2.ads: Likewise.
	* gnat.dg/sso: New directory.

 c-c++-common/sso-1.c     |   94 +++++++++++++++++++++++++++++++++++
 c-c++-common/sso/dump.h  |   23 ++++++++
 c-c++-common/sso/init1.h |   12 ++++
 c-c++-common/sso/init2.h |   24 +++++++++
 c-c++-common/sso/init3.h |   34 ++++++++++++
 c-c++-common/sso/init4.h |   14 +++++
 c-c++-common/sso/init5.h |   14 +++++
 c-c++-common/sso/init6.h |   24 +++++++++
 c-c++-common/sso/init7.h |   28 ++++++++++
 c-c++-common/sso/init8.h |   28 ++++++++++
 c-c++-common/sso/init9.h |   14 +++++
 c-c++-common/sso/p1.c    |   64 ++++++++++++++++++++++++
 c-c++-common/sso/p2.c    |   88 +++++++++++++++++++++++++++++++++
 c-c++-common/sso/p3.c    |   88 +++++++++++++++++++++++++++++++++
 c-c++-common/sso/p4.c    |   64 ++++++++++++++++++++++++
 c-c++-common/sso/p5.c    |   74 ++++++++++++++++++++++++++++
 c-c++-common/sso/p6.c    |   74 ++++++++++++++++++++++++++++
 c-c++-common/sso/p7.c    |   74 ++++++++++++++++++++++++++++
 c-c++-common/sso/p8.c    |   74 ++++++++++++++++++++++++++++
 c-c++-common/sso/p9.c    |   64 ++++++++++++++++++++++++
 c-c++-common/sso/q1.c    |   50 +++++++++++++++++++
 c-c++-common/sso/q2.c    |   54 ++++++++++++++++++++
 c-c++-common/sso/q3.c    |   54 ++++++++++++++++++++
 c-c++-common/sso/q4.c    |   50 +++++++++++++++++++
 c-c++-common/sso/q5.c    |   46 +++++++++++++++++
 c-c++-common/sso/q6.c    |   45 +++++++++++++++++
 c-c++-common/sso/q7.c    |   46 +++++++++++++++++
 c-c++-common/sso/q8.c    |   46 +++++++++++++++++
 c-c++-common/sso/q9.c    |   50 +++++++++++++++++++
 c-c++-common/sso/r3.c    |   65 ++++++++++++++++++++++++
 c-c++-common/sso/r5.c    |   65 ++++++++++++++++++++++++
 c-c++-common/sso/r6.c    |   65 ++++++++++++++++++++++++
 c-c++-common/sso/r7.c    |   65 ++++++++++++++++++++++++
 c-c++-common/sso/r8.c    |   65 ++++++++++++++++++++++++
 c-c++-common/sso/s3.c    |   79 ++++++++++++++++++++++++++++++
 c-c++-common/sso/s5.c    |   91 ++++++++++++++++++++++++++++++++++
 c-c++-common/sso/s6.c    |   81 ++++++++++++++++++++++++++++++
 c-c++-common/sso/s7.c    |   79 ++++++++++++++++++++++++++++++
 c-c++-common/sso/s8.c    |   79 ++++++++++++++++++++++++++++++
 c-c++-common/sso/t1.c    |   56 +++++++++++++++++++++
 c-c++-common/sso/t2.c    |   92 +++++++++++++++++++++++++++++++++++
 c-c++-common/sso/t3.c    |   92 +++++++++++++++++++++++++++++++++++
 c-c++-common/sso/t4.c    |   56 +++++++++++++++++++++
 c-c++-common/sso/t5.c    |   72 +++++++++++++++++++++++++++
 c-c++-common/sso/t6.c    |   72 +++++++++++++++++++++++++++
 c-c++-common/sso/t7.c    |   72 +++++++++++++++++++++++++++
 c-c++-common/sso/t8.c    |   72 +++++++++++++++++++++++++++
 c-c++-common/sso/t9.c    |   56 +++++++++++++++++++++
 c-c++-common/sso/u5.c    |   52 +++++++++++++++++++
 c-c++-common/sso/u6.c    |   52 +++++++++++++++++++
 g++.dg/sso-1.C           |   17 ++++++
 g++.dg/sso/sso.exp       |   40 +++++++++++++++
 gcc.dg/sso-1.c           |   17 ++++++
 gcc.dg/sso/sso.exp       |   40 +++++++++++++++
 gnat.dg/specs/sso1.ads   |   22 ++++++++
 gnat.dg/specs/sso2.ads   |   26 +++++++++
 gnat.dg/sso/conv1.adb    |   50 +++++++++++++++++++
 gnat.dg/sso/dump.adb     |   17 ++++++
 gnat.dg/sso/dump.ads     |    3 +
 gnat.dg/sso/init1.ads    |   26 +++++++++
 gnat.dg/sso/init10.ads   |   23 ++++++++
 gnat.dg/sso/init11.ads   |   34 ++++++++++++
 gnat.dg/sso/init12.ads   |   25 +++++++++
 gnat.dg/sso/init2.ads    |   69 ++++++++++++++++++++++++++
 gnat.dg/sso/init3.ads    |   78 +++++++++++++++++++++++++++++
 gnat.dg/sso/init4.ads    |   27 ++++++++++
 gnat.dg/sso/init5.ads    |   39 ++++++++++++++
 gnat.dg/sso/init6.ads    |   39 ++++++++++++++
 gnat.dg/sso/init7.ads    |   59 ++++++++++++++++++++++
 gnat.dg/sso/init8.ads    |   59 ++++++++++++++++++++++
 gnat.dg/sso/init9.ads    |   27 ++++++++++
 gnat.dg/sso/p1.adb       |   62 +++++++++++++++++++++++
 gnat.dg/sso/p10.adb      |   63 ++++++++++++++++++++++++
 gnat.dg/sso/p11.adb      |   68 +++++++++++++++++++++++++
 gnat.dg/sso/p12.adb      |  122 +++++++++++++++++++++++++++++++++++++++++++++
 gnat.dg/sso/p2.adb       |   80 ++++++++++++++++++++++++++++++
 gnat.dg/sso/p3.adb       |   80 ++++++++++++++++++++++++++++++
 gnat.dg/sso/p4.adb       |   63 ++++++++++++++++++++++++
 gnat.dg/sso/p5.adb       |   68 +++++++++++++++++++++++++
 gnat.dg/sso/p6.adb       |   61 +++++++++++++++++++++++
 gnat.dg/sso/p7.adb       |   61 +++++++++++++++++++++++
 gnat.dg/sso/p8.adb       |   61 +++++++++++++++++++++++
 gnat.dg/sso/p9.adb       |   63 ++++++++++++++++++++++++
 gnat.dg/sso/q1.adb       |   52 +++++++++++++++++++
 gnat.dg/sso/q10.adb      |   53 ++++++++++++++++++++
 gnat.dg/sso/q11.adb      |   44 ++++++++++++++++
 gnat.dg/sso/q12.adb      |   43 ++++++++++++++++
 gnat.dg/sso/q2.adb       |   60 ++++++++++++++++++++++
 gnat.dg/sso/q3.adb       |   60 ++++++++++++++++++++++
 gnat.dg/sso/q4.adb       |   53 ++++++++++++++++++++
 gnat.dg/sso/q5.adb       |   44 ++++++++++++++++
 gnat.dg/sso/q6.adb       |   44 ++++++++++++++++
 gnat.dg/sso/q7.adb       |   44 ++++++++++++++++
 gnat.dg/sso/q8.adb       |   44 ++++++++++++++++
 gnat.dg/sso/q9.adb       |   53 ++++++++++++++++++++
 gnat.dg/sso/r11.adb      |   68 +++++++++++++++++++++++++
 gnat.dg/sso/r12.adb      |  123 +++++++++++++++++++++++++++++++++++++++++++++
 gnat.dg/sso/r3.adb       |   68 +++++++++++++++++++++++++
 gnat.dg/sso/r5.adb       |   68 +++++++++++++++++++++++++
 gnat.dg/sso/r6.adb       |   68 +++++++++++++++++++++++++
 gnat.dg/sso/r7.adb       |   68 +++++++++++++++++++++++++
 gnat.dg/sso/r8.adb       |   68 +++++++++++++++++++++++++
 gnat.dg/sso/s11.adb      |   78 +++++++++++++++++++++++++++++
 gnat.dg/sso/s12.adb      |   77 +++++++++++++++++++++++++++++
 gnat.dg/sso/s3.adb       |   79 ++++++++++++++++++++++++++++++
 gnat.dg/sso/s5.adb       |   78 +++++++++++++++++++++++++++++
 gnat.dg/sso/s6.adb       |   79 ++++++++++++++++++++++++++++++
 gnat.dg/sso/s7.adb       |   79 ++++++++++++++++++++++++++++++
 gnat.dg/sso/s8.adb       |   79 ++++++++++++++++++++++++++++++
 gnat.dg/sso/sso.exp      |   40 +++++++++++++++
 gnat.dg/sso/t1.adb       |   55 +++++++++++++++++++++
 gnat.dg/sso/t10.adb      |   56 +++++++++++++++++++++
 gnat.dg/sso/t11.adb      |   67 +++++++++++++++++++++++++
 gnat.dg/sso/t12.adb      |   66 +++++++++++++++++++++++++
 gnat.dg/sso/t2.adb       |   84 ++++++++++++++++++++++++++++++++
 gnat.dg/sso/t3.adb       |   84 ++++++++++++++++++++++++++++++++
 gnat.dg/sso/t4.adb       |   56 +++++++++++++++++++++
 gnat.dg/sso/t5.adb       |   67 +++++++++++++++++++++++++
 gnat.dg/sso/t6.adb       |   67 +++++++++++++++++++++++++
 gnat.dg/sso/t7.adb       |   68 +++++++++++++++++++++++++
 gnat.dg/sso/t8.adb       |   68 +++++++++++++++++++++++++
 gnat.dg/sso/t9.adb       |   56 +++++++++++++++++++++
 gnat.dg/sso/u11.adb      |   44 ++++++++++++++++
 gnat.dg/sso/u5.adb       |   44 ++++++++++++++++
 gnat.dg/sso/u6.adb       |   44 ++++++++++++++++
 gnat.dg/sso1.adb         |   77 +++++++++++++++++++++++++++++
 gnat.dg/sso2.adb         |   14 +++++
 gnat.dg/sso2.ads         |   13 ++++
 gnat.dg/sso3.adb         |   52 +++++++++++++++++++
 gnat.dg/sso4.adb         |   55 +++++++++++++++++++++
 gnat.dg/sso5.adb         |   52 +++++++++++++++++++
 gnat.dg/sso6.adb         |   54 ++++++++++++++++++++
 gnat.dg/sso7.adb         |   52 +++++++++++++++++++
 133 files changed, 7490 insertions(+)

-- 
Eric Botcazou

[-- Attachment #2: sso-testsuite.diff --]
[-- Type: text/x-patch, Size: 217663 bytes --]

Index: gcc/testsuite/gnat.dg/sso6.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso6.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso6.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,54 @@
+-- { dg-do run }
+
+with System;
+
+procedure SSO6 is
+
+   type Short_Int is mod 2**16;
+
+   type Rec1 is record
+      F1 : Short_Int;
+      F2 : Short_Int;
+   end record;
+   for Rec1 use record
+      F1 at 0 range  0 .. 15;
+      F2 at 0 range 16 .. 31;
+   end record;
+   for Rec1'Bit_Order use System.High_Order_First;
+   for Rec1'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec2 is record
+      I1 : Integer;
+      R1 : Rec1;
+   end record;
+   for Rec2 use record
+      I1 at 0 range 0 .. 31; 
+      R1 at 4 range 0 .. 31;
+   end record;
+   for Rec2'Bit_Order use System.High_Order_First;
+   for Rec2'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec3 is record
+      Data : Rec1;
+   end record;
+   for Rec3 use record
+      Data at 0 range 1 .. 32;
+   end record;
+   for Rec3'Bit_Order use System.High_Order_First;
+   for Rec3'Scalar_Storage_Order use System.High_Order_First;
+
+   procedure Copy (Message : in Rec3) is
+      Local : Rec2;
+   begin
+      Local := (I1 => 1, R1 => Message.Data);
+      if Local.R1 /= Message.Data then
+         raise Program_Error;
+      end if;
+   end;
+
+   Message : Rec3;
+
+begin
+   Message := (Data => (2, 3));
+   Copy(Message);
+end;
Index: gcc/testsuite/gnat.dg/sso/t7.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t7.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t7.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init7; use Init7;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T7 is
+  Verbose : constant Boolean := False;
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.N.C1 := My_R1.N.C1 + 1;
+  Local_R1.N.C2 := My_R1.N.C2 + 1;
+  Local_R1.N.C3 := My_R1.N.C3 + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.N.C1 := My_R2.N.C1 + 1;
+  Local_R2.N.C2 := My_R2.N.C2 + 1;
+  Local_R2.N.C3 := My_R2.N.C3 + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+-- 
+  Local_R1 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.N.C1 := Local_R1.N.C1 + 1;
+  Local_R1.N.C2 := Local_R1.N.C2 + 1;
+  Local_R1.N.C3 := Local_R1.N.C3 + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.N.C1 := Local_R2.N.C1 + 1;
+  Local_R2.N.C2 := Local_R2.N.C2 + 1;
+  Local_R2.N.C3 := Local_R2.N.C3 + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/t8.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t8.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t8.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init8; use Init8;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T8 is
+  Verbose : constant Boolean := False;
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.N.C1 := My_R1.N.C1 + 1;
+  Local_R1.N.C2 := My_R1.N.C2 + 1;
+  Local_R1.N.C3 := My_R1.N.C3 + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.N.C1 := My_R2.N.C1 + 1;
+  Local_R2.N.C2 := My_R2.N.C2 + 1;
+  Local_R2.N.C3 := My_R2.N.C3 + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.N.C1 := Local_R1.N.C1 + 1;
+  Local_R1.N.C2 := Local_R1.N.C2 + 1;
+  Local_R1.N.C3 := Local_R1.N.C3 + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.N.C1 := Local_R2.N.C1 + 1;
+  Local_R2.N.C2 := Local_R2.N.C2 + 1;
+  Local_R2.N.C3 := Local_R2.N.C3 + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/t9.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t9.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t9.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,56 @@
+-- { dg-do run }
+
+with Init9; use Init9;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T9 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.F := My_R1.F + 1.0;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 8c 16 22 aa fd 90 10 40\n" }
+
+  Local_R2.F := My_R2.F + 1.0;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 10 90 fd aa 22 16 8c\n" }
+
+  Local_R1.F := Pi;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Local_R2.F := Pi;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" }
+
+  Local_R1.F := Local_R1.F + 1.0;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 8c 16 22 aa fd 90 10 40\n" }
+
+  Local_R2.F := Local_R2.F + 1.0;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 10 90 fd aa 22 16 8c\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/q10.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q10.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q10.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,53 @@
+-- { dg-do run }
+-- { dg-options "-gnatws" }
+
+with Init10; use Init10;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q10 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78\n" }
+
+  if A1.I /= B1.I then
+    raise Program_Error;
+  end if;
+
+  if A1.I /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/q11.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q11.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q11.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q11 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n"} 
+
+  if A1.I /= B1.I or A1.A(1) /= B1.A(1) then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.A(1) /= B2.A(1) then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/q12.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q12.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q12.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,43 @@
+-- { dg-do run }
+
+with Init12; use Init12;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q12 is
+
+  A1  : Arr1  := My_A1;
+  A11 : Arr11 := My_A11;
+
+  A2  : Arr2  := My_A2;
+  A22 : Arr22 := My_A22;
+
+begin
+  Put ("A1  :");
+  Dump (A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1  : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A11 :");
+  Dump (A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Put ("A2  :");
+  Dump (A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2  : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A22 :");
+  Dump (A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  if A1(1) /= A11(1,1) then
+    raise Program_Error;
+  end if;
+
+  if A2(1) /= A22(1,1) then
+    raise Program_Error;
+  end if;
+end;
Index: gcc/testsuite/gnat.dg/sso/s11.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/s11.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/s11.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,78 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S11 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  AA1 : Arr1;
+  AA2 : Arr2;
+
+  C1 : My_Integer;
+  C2 : My_Integer;
+  C3 : My_Integer;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  AA1 := A1.A;
+  C1 := AA1(1);
+  C2 := AA1(2);
+  C3 := AA1(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA1(1) := C1;
+  AA1(2) := C2;
+  AA1(3) := C3;
+  A1.A := AA1;
+
+  AA2 := A2.A;
+  C1 := AA2(1);
+  C2 := AA2(2);
+  C3 := AA2(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA2(1) := C1;
+  AA2(2) := C2;
+  AA2(3) := C3;
+  A2.A := AA2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/s12.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/s12.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/s12.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,77 @@
+-- { dg-do run }
+
+with Init12; use Init12;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S12 is
+
+  A11 : Arr11 := My_A11;
+  A22 : Arr22 := My_A22;
+
+  A1 : Arr1;
+  A2 : Arr2;
+
+  C1 : Integer;
+  C2 : Integer;
+  C3 : Integer;
+
+begin
+  Put ("A11 :");
+  Dump (A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Put ("A22 :");
+  Dump (A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  A1 := (A11(1,1), A11(1,2), A11(2,1));
+  C1 := A1(1);
+  C2 := A1(2);
+  C3 := A1(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 11206674\n" }
+
+  A1(1) := C1;
+  A1(2) := C2;
+  A1(3) := C3;
+  A11(1,1) := A1(1); A11(1,2) := A1(2); A11(2,1) := A1(3);
+
+  A2 := (A22(1,1), A22(1,2), A22(2,1));
+  C1 := A2(1);
+  C2 := A2(2);
+  C3 := A2(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 11206674\n" }
+
+  A2(1) := C1;
+  A2(2) := C2;
+  A2(3) := C3;
+  A22(1,1) := A2(1); A22(1,2) := A2(2); A22(2,1) := A2(3);
+
+  Put ("A11 :");
+  Dump (A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Put ("A22 :");
+  Dump (A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/u11.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/u11.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/u11.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure U11 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+  C1 : My_Integer;
+  C2 : My_Integer;
+
+begin
+  Local_R1 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 01 00 00 00 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 00 00 00 01 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  C1 := Local_R1.A (Integer(Local_R1.I));
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Local_R1.I := Local_R1.I + 1;  
+  C1 := Local_R1.A (Integer(Local_R1.I));
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 13434932\n" }
+
+  C2 := Local_R2.A (Integer(Local_R2.I));
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 11206674\n" }
+
+  Local_R2.I := Local_R2.I + 1;  
+  C2 := Local_R2.A (Integer(Local_R2.I));
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/q1.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q1.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q1.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,52 @@
+-- { dg-do run }
+
+with Init1; use Init1;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q1 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78\n" }
+
+  if A1.I /= B1.I then
+    raise Program_Error;
+  end if;
+
+  if A1.I /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/q2.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q2.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q2.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,60 @@
+-- { dg-do run }
+
+with Init2; use Init2;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q2 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  if A1.S1 /= B1.S1 then
+    raise Program_Error;
+  end if;
+
+  if A1.S1 /= 2 then
+    raise Program_Error;
+  end if;
+
+  if A2.S1 /= B2.S1 then
+    raise Program_Error;
+  end if;
+
+  if A2.S1 /= 2 then
+    raise Program_Error;
+  end if;
+
+  if A1.I /= B1.I or A1.A(1) /= B1.A(1) then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.A(1) /= B2.A(1) then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/q3.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q3.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q3.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,60 @@
+-- { dg-do run }
+
+with Init3; use Init3;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q3 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  if A1.S1 /= B1.S1 then
+    raise Program_Error;
+  end if;
+
+  if A1.S1 /= 2 then
+    raise Program_Error;
+  end if;
+
+  if A2.S1 /= B2.S1 then
+    raise Program_Error;
+  end if;
+
+  if A2.S1 /= 2 then
+    raise Program_Error;
+  end if;
+
+  if A1.I /= B1.I or A1.N.C1 /= B1.N.C1 then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.N.C1 /= B2.N.C1 then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/q4.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q4.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q4.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,53 @@
+-- { dg-do run }
+
+with Init4; use Init4;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q4 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : db 0f 49 40\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : db 0f 49 40\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 40 49 0f db\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 40 49 0f db\n" }
+
+  if A1.F /= B1.F then
+    raise Program_Error;
+  end if;
+
+  if A1.F /= Pi then
+    raise Program_Error;
+  end if;
+
+  if A2.F /= B2.F then
+    raise Program_Error;
+  end if;
+
+  if A2.F /= Pi then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/init10.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init10.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init10.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,23 @@
+with System;
+
+package Init10 is
+
+  type My_Integer is new Integer;
+  for My_Integer'Alignment use 1;
+
+  type R1 is record
+    I : My_Integer;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R2 is record
+    I : My_Integer;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+
+  My_R1 : constant R1 := (I => 16#12345678#);
+  My_R2 : constant R2 := (I => 16#12345678#);
+
+end Init10;
Index: gcc/testsuite/gnat.dg/sso/q5.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q5.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q5.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q5 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n"} 
+
+  if A1.I /= B1.I or A1.A(1) /= B1.A(1) then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.A(1) /= B2.A(1) then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/q6.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q6.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q6.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q6 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  if A1.I /= B1.I or A1.A(1) /= B1.A(1) then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.A(1) /= B2.A(1) then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/init11.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init11.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init11.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,34 @@
+with System;
+
+package Init11 is
+
+  type My_Integer is new Integer;
+  for My_Integer'Alignment use 1;
+
+  type Arr1 is array (1 .. 3) of My_Integer;
+  for Arr1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R1 is record
+    I : My_Integer;
+    A : Arr1;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type Arr2 is array (1 .. 3) of My_Integer;
+  for Arr2'Scalar_Storage_Order use System.High_Order_First;
+
+  type R2 is record
+    I : My_Integer;
+    A : Arr2;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+
+  My_R1 : constant R1 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+  My_R2 : constant R2 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+end Init11;
Index: gcc/testsuite/gnat.dg/sso/conv1.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/conv1.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/conv1.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,50 @@
+-- { dg-do run }
+
+with System; use System;
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure Conv1 is
+   type Short is mod 2**16;
+
+   type R_L is record
+      S : Short;
+      C : Character;
+   end record;
+   for R_L'Bit_Order use Low_Order_First;
+   for R_L'Scalar_Storage_Order use Low_Order_First;
+   for R_L use record
+      S at 0 range 0 .. 15;
+      C at 2 range 0 .. 7;
+   end record;
+
+   type R_H is new R_L;
+   for R_H'Bit_Order use High_Order_First;
+   for R_H'Scalar_Storage_Order use High_Order_First;
+   for R_H use record
+      S at 0 range 0 .. 15;
+      C at 2 range 0 .. 7;
+   end record;
+
+   procedure Dump (Name : String; S : Short; C : Character) is
+   begin
+      Put_Line (Name & " = (S =>" & S'Img & ", C => '" & C & "')");
+   end Dump;
+
+   X_L : R_L;
+   X_H : R_H;
+begin
+   X_L.S := 12345;
+   X_L.C := 'a';
+   Dump ("X_L", X_L.S, X_L.C);
+   -- { dg-output "X_L = \\(S => 12345, C => 'a'\\)\n" }
+
+   X_H.S := 23456;
+   X_H.C := 'b';
+   Dump ("X_H", X_H.S, X_H.C);
+   -- { dg-output "X_H = \\(S => 23456, C => 'b'\\)\n" }
+
+   X_H := R_H (X_L);
+   Dump ("X_H", X_H.S, X_H.C);
+   -- { dg-output "X_H = \\(S => 12345, C => 'a'\\)\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/q7.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q7.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q7.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init7; use Init7;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q7 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  if A1.I /= B1.I or A1.N.C1 /= B1.N.C1 then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.N.C1 /= B2.N.C1 then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/init12.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init12.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init12.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,25 @@
+with System;
+
+package Init12 is
+
+  type Arr1 is array (1 .. 3) of Integer;
+  for Arr1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type Arr11 is array (1 .. 2, 1 .. 2) of Integer;
+  for Arr11'Scalar_Storage_Order use System.Low_Order_First;
+
+  type Arr2 is array (1 .. 3) of Integer;
+  for Arr2'Scalar_Storage_Order use System.High_Order_First;
+
+  type Arr22 is array (1 .. 2, 1 .. 2) of Integer;
+  for Arr22'Scalar_Storage_Order use System.High_Order_First;
+
+  My_A1   : constant Arr1   := (16#AB0012#, 16#CD0034#, 16#EF0056#);
+  My_A11  : constant Arr11  := (1 => (16#AB0012#, 16#CD0034#),
+                                2 => (16#AB0012#, 16#CD0034#));
+
+  My_A2   : constant Arr2   := (16#AB0012#, 16#CD0034#, 16#EF0056#);
+  My_A22  : constant Arr22  := (1 => (16#AB0012#, 16#CD0034#),
+                                2 => (16#AB0012#, 16#CD0034#));
+
+end Init12;
Index: gcc/testsuite/gnat.dg/sso/q8.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q8.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q8.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init8; use Init8;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q8 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  if A1.I /= B1.I or A1.N.C1 /= B1.N.C1 then
+    raise Program_Error;
+  end if;
+
+  if A2.I /= B2.I or A2.N.C1 /= B2.N.C1 then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/q9.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/q9.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/q9.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,53 @@
+-- { dg-do run }
+
+with Init9; use Init9;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure Q9 is
+
+  A1 : R1 := My_R1;
+  B1 : R1 := My_R1;
+
+  A2 : R2 := My_R2;
+  B2 : R2 := My_R2;
+
+begin
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Put ("B1 :");
+  Dump (B1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 40 09 21 fb 54 44 2d 18\n" }
+
+  Put ("B2 :");
+  Dump (B2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "B2 : 40 09 21 fb 54 44 2d 18\n" }
+
+  if A1.F /= B1.F then
+    raise Program_Error;
+  end if;
+
+  if A1.F /= Pi then
+    raise Program_Error;
+  end if;
+
+  if A2.F /= B2.F then
+    raise Program_Error;
+  end if;
+
+  if A2.F /= Pi then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/u5.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/u5.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/u5.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure U5 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+  C1 : Integer;
+  C2 : Integer;
+
+begin
+  Local_R1 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 01 00 00 00 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 00 00 00 01 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  C1 := Local_R1.A (Local_R1.I);
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Local_R1.I := Local_R1.I + 1;  
+  C1 := Local_R1.A (Local_R1.I);
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 13434932\n" }
+
+  C2 := Local_R2.A (Local_R2.I);
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 11206674\n" }
+
+  Local_R2.I := Local_R2.I + 1;  
+  C2 := Local_R2.A (Local_R2.I);
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/u6.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/u6.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/u6.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,44 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure U6 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+  C1 : Integer;
+  C2 : Integer;
+
+begin
+  Local_R1 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 01 00 00 00 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R2 := (I => 1, A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 00 00 00 01 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  C1 := Local_R1.A (Local_R1.I);
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Local_R1.I := Local_R1.I + 1;  
+  C1 := Local_R1.A (Local_R1.I);
+  Put_Line ("C1 :" & C1'Img);
+  -- { dg-output "C1 : 13434932\n" }
+
+  C2 := Local_R2.A (Local_R2.I);
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 11206674\n" }
+
+  Local_R2.I := Local_R2.I + 1;  
+  C2 := Local_R2.A (Local_R2.I);
+  Put_Line ("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/r3.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/r3.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/r3.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init3; use Init3;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R3 is
+
+  function Get_Elem (R : R1) return Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.I;
+  end;
+
+  procedure Set_Elem (R : access R1; I : Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.I := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.I;
+  end;
+
+  procedure Set_Elem (R : access R2; I : Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.I := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  --  { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  if Get_Elem (A1) /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#12345678# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/r5.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/r5.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/r5.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R5 is
+
+  function Get_Elem (R : R1) return Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R1; I : Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R2; I : Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/r6.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/r6.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/r6.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R6 is
+
+  function Get_Elem (R : R1) return Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R1; I : Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R2; I : Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/r7.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/r7.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/r7.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init7; use Init7;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R7 is
+
+  function Get_Elem (R : R1) return Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.N.C1;
+  end;
+
+  procedure Set_Elem (R : access R1; I : Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.N.C1 := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.N.C1;
+  end;
+
+  procedure Set_Elem (R : access R2; I : Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.N.C1 := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/r8.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/r8.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/r8.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init8; use Init8;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R8 is
+
+  function Get_Elem (R : R1) return Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.N.C1;
+  end;
+
+  procedure Set_Elem (R : access R1; I : Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.N.C1 := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.N.C1;
+  end;
+
+  procedure Set_Elem (R : access R2; I : Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.N.C1 := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/p10.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p10.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p10.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,63 @@
+-- { dg-do run }
+-- { dg-options "-gnatws" }
+
+with Init10; use Init10;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P10 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := 16#12345678#;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := 16#12345678#;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := Local_R2.I;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := Local_R1.I;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/p11.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p11.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p11.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P11 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1.I    := Local_R2.I;
+  Local_R1.A(1) := Local_R2.A(1);
+  Local_R1.A(2) := Local_R2.A(2);
+  Local_R1.A(3) := Local_R2.A(3);
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2.I    := Local_R1.I;
+  Local_R2.A(1) := Local_R1.A(1);
+  Local_R2.A(2) := Local_R1.A(2);
+  Local_R2.A(3) := Local_R1.A(3);
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/p12.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p12.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p12.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,122 @@
+-- { dg-do run }
+
+with Init12; use Init12;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P12 is
+
+  Local_A1  : Arr1;
+  Local_A11 : Arr11;
+  Local_A2  : Arr2;
+  Local_A22 : Arr22;
+
+begin
+  Put ("My_A1     :");
+  Dump (My_A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_A1     : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("My_A11    :");
+  Dump (My_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_A11    : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Put ("My_A2     :");
+  Dump (My_A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_A2     : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("My_A22    :");
+  Dump (My_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_A22    : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  Local_A1 := My_A1;
+  Put ("Local_A1  :");
+  Dump (Local_A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A1  : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_A11 := My_A11;
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Local_A2 := My_A2;
+  Put ("Local_A2  :");
+  Dump (Local_A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A2  : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_A22 := My_A22;
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  Local_A1 := (16#AB0012#, 16#CD0034#, 16#EF0056#);
+  Put ("Local_A1  :");
+  Dump (Local_A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A1  : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_A11 := (1 => (16#AB0012#, 16#CD0034#),
+                2 => (16#AB0012#, 16#CD0034#));
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Local_A2 := (16#AB0012#, 16#CD0034#, 16#EF0056#);
+  Put ("Local_A2  :");
+  Dump (Local_A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A2  : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_A22 := (1 => (16#AB0012#, 16#CD0034#),
+                2 => (16#AB0012#, 16#CD0034#));
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  Local_A1(1) := Local_A2(1);
+  Local_A1(2) := Local_A2(2);
+  Local_A1(3) := Local_A2(3);
+
+  Put ("Local_A1  :");
+  Dump (Local_A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A1  : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_A11(1,1) := Local_A22(1,1);
+  Local_A11(1,2) := Local_A22(1,2);
+  Local_A11(2,1) := Local_A22(2,1);
+  Local_A11(2,2) := Local_A22(2,2);
+
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Local_A2(1) := Local_A1(1);
+  Local_A2(2) := Local_A1(2);
+  Local_A2(3) := Local_A1(3);
+
+  Put ("Local_A2  :");
+  Dump (Local_A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A2  : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_A22(1,1) := Local_A11(1,1);
+  Local_A22(1,2) := Local_A11(1,2);
+  Local_A22(2,1) := Local_A11(2,1);
+  Local_A22(2,2) := Local_A11(2,2);
+
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/r11.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/r11.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/r11.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R11 is
+
+  function Get_Elem (R : R1) return My_Integer is
+    Tmp : R1 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R1; I : My_Integer) is
+    Tmp : R1 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  function Get_Elem (R : R2) return My_Integer is
+    Tmp : R2 := R;
+  begin
+    return Tmp.A(1);
+  end;
+
+  procedure Set_Elem (R : access R2; I : My_Integer) is
+    Tmp : R2 := R.all;
+  begin
+    Tmp.A(1) := I;
+    R.all := Tmp;
+  end;
+
+  A1 : aliased R1 := My_R1;
+  A2 : aliased R2 := My_R2;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+end;
Index: gcc/testsuite/gnat.dg/sso/r12.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/r12.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/r12.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,123 @@
+-- { dg-do run }
+
+with Init12; use Init12;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure R12 is
+
+  function Get_Elem (A : Arr1) return Integer is
+    Tmp : Arr1 := A;
+  begin
+    return Tmp(1);
+  end;
+
+  procedure Set_Elem (A : access Arr1; I : Integer) is
+    Tmp : Arr1 := A.all;
+  begin
+    Tmp(1) := I;
+    A.all := Tmp;
+  end;
+
+  function Get_Elem (A : Arr11) return Integer is
+    Tmp : Arr11 := A;
+  begin
+    return Tmp(1,1);
+  end;
+
+  procedure Set_Elem (A : access Arr11; I : Integer) is
+    Tmp : Arr11 := A.all;
+  begin
+    Tmp(1,1) := I;
+    A.all := Tmp;
+  end;
+
+  function Get_Elem (A : Arr2) return Integer is
+    Tmp : Arr2 := A;
+  begin
+    return Tmp(1);
+  end;
+
+  procedure Set_Elem (A : access Arr2; I : Integer) is
+    Tmp : Arr2 := A.all;
+  begin
+    Tmp(1) := I;
+    A.all := Tmp;
+  end;
+
+  function Get_Elem (A : Arr22) return Integer is
+    Tmp : Arr22 := A;
+  begin
+    return Tmp(1,1);
+  end;
+
+  procedure Set_Elem (A : access Arr22; I : Integer) is
+    Tmp : Arr22 := A.all;
+  begin
+    Tmp(1,1) := I;
+    A.all := Tmp;
+  end;
+
+  A1  : aliased Arr1  := My_A1;
+  A11 : aliased Arr11 := My_A11;
+
+  A2  : aliased Arr2  := My_A2;
+  A22 : aliased Arr22 := My_A22;
+
+begin
+  Put ("A1  :");
+  Dump (A1'Address, Arr1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1  : 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A11 :");
+  Dump (A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\n" }
+
+  Put ("A2  :");
+  Dump (A2'Address, Arr2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2  : 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A22 :");
+  Dump (A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  if Get_Elem (A1) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A1'Access, 16#CD0034#);
+  if Get_Elem (A1) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A11) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A11'Access, 16#CD0034#);
+  if Get_Elem (A11) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A2) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A2'Access, 16#CD0034#);
+  if Get_Elem (A2) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+
+  if Get_Elem (A22) /= 16#AB0012# then
+    raise Program_Error;
+  end if;
+
+  Set_Elem (A22'Access, 16#CD0034#);
+  if Get_Elem (A22) /= 16#CD0034# then
+    raise Program_Error;
+  end if;
+end;
Index: gcc/testsuite/gnat.dg/sso/t10.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t10.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t10.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,56 @@
+-- { dg-do run }
+-- { dg-options "-gnatws" }
+
+with Init10; use Init10;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T10 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I := My_R1.I + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12\n" }
+
+  Local_R2.I := My_R2.I + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79\n" }
+
+  Local_R1.I := 16#12345678#;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := 16#12345678#;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := Local_R1.I + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12\n" }
+
+  Local_R2.I := Local_R2.I + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/init1.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init1.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init1.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,26 @@
+with System;
+
+package Init1 is
+
+  type R1 is record
+    I : Integer;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    I at 0 range 0 .. 31;
+  end record;
+
+  type R2 is record
+    I : Integer;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    I at 0 range 0 .. 31;
+  end record;
+
+  My_R1 : constant R1 := (I => 16#12345678#);
+  My_R2 : constant R2 := (I => 16#12345678#);
+
+end Init1;
Index: gcc/testsuite/gnat.dg/sso/t11.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t11.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t11.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,67 @@
+-- { dg-do run }
+
+with Init11; use Init11;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T11 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.A(1) := My_R1.A(1) + 1;
+  Local_R1.A(2) := My_R1.A(2) + 1;
+  Local_R1.A(3) := My_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.A(1) := My_R2.A(1) + 1;
+  Local_R2.A(2) := My_R2.A(2) + 1;
+  Local_R2.A(3) := My_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.A(1) := Local_R1.A(1) + 1;
+  Local_R1.A(2) := Local_R1.A(2) + 1;
+  Local_R1.A(3) := Local_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.A(1) := Local_R2.A(1) + 1;
+  Local_R2.A(2) := Local_R2.A(2) + 1;
+  Local_R2.A(3) := Local_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/init2.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init2.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init2.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,69 @@
+with System;
+
+package Init2 is
+
+  type Small is mod 2**2;
+  for Small'Size use 2;
+
+  type Count is mod 2**9;
+  for Count'Size use 9;
+
+  type Arr1 is array (1 .. 3) of Count;
+  pragma Pack (Arr1);
+  for Arr1'Size use 27;
+  for Arr1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R1 is record
+    S1 : Small;
+    I  : Integer;
+    S2 : Small;
+    A  : Arr1;
+    B  : Boolean;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    S1 at 0 range  0 ..  1;
+    I  at 0 range  2 .. 33;
+    S2 at 0 range 34 .. 35;
+    A  at 0 range 36 .. 62;
+    B  at 0 range 63 .. 63;
+  end record;
+  for R1'Size use 64;
+
+  type Arr2 is array (1 .. 3) of Count;
+  pragma Pack (Arr2);
+  for Arr2'Size use 27;
+  for Arr2'Scalar_Storage_Order use System.High_Order_First;
+
+  type R2 is record
+    S1 : Small;
+    I  : Integer;
+    S2 : Small;
+    A  : Arr2;
+    B  : Boolean;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    S1 at 0 range  0 ..  1;
+    I  at 0 range  2 .. 33;
+    S2 at 0 range 34 .. 35;
+    A  at 0 range 36 .. 62;
+    B  at 0 range 63 .. 63;
+  end record;
+  for R2'Size use 64;
+
+  My_R1 : constant R1 := (S1 => 2,
+                          I  => 16#12345678#,
+                          S2 => 1,
+                          A  => (16#AB#, 16#CD#, 16#EF#),
+                          B  => True);
+
+  My_R2 : constant R2 := (S1 => 2,
+                          I  => 16#12345678#,
+                          S2 => 1,
+                          A  => (16#AB#, 16#CD#, 16#EF#),
+                          B  => True);
+
+end Init2;
Index: gcc/testsuite/gnat.dg/sso/t12.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t12.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t12.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,66 @@
+-- { dg-do run }
+-- 
+with Init12; use Init12;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T12 is
+
+  Local_A11 : Arr11;
+  Local_A22 : Arr22;
+
+begin
+  Local_A11(1,1) := My_A11(1,1) + 1;
+  Local_A11(1,2) := My_A11(1,2) + 1;
+  Local_A11(2,1) := My_A11(2,1) + 1;
+  Local_A11(2,2) := My_A11(2,2) + 1;
+
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 13 00 ab 00 35 00 cd 00 13 00 ab 00 35 00 cd 00\n" }
+
+  Local_A22(1,1) := My_A22(1,1) + 1;
+  Local_A22(1,2) := My_A22(1,2) + 1;
+  Local_A22(2,1) := My_A22(2,1) + 1;
+  Local_A22(2,2) := My_A22(2,2) + 1;
+
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 13 00 cd 00 35 00 ab 00 13 00 cd 00 35\n" }
+
+  Local_A11 := (1 => (16#AB0012#, 16#CD0034#),
+                2 => (16#AB0012#, 16#CD0034#));
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 12 00 ab 00 34 00 cd 00 12 00 ab 00 34 00 cd 00\\n" }
+
+  Local_A22 := (1 => (16#AB0012#, 16#CD0034#),
+                2 => (16#AB0012#, 16#CD0034#));
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 12 00 cd 00 34 00 ab 00 12 00 cd 00 34\n" }
+
+  Local_A11(1,1) := Local_A11(1,1) + 1;
+  Local_A11(1,2) := Local_A11(1,2) + 1;
+  Local_A11(2,1) := Local_A11(2,1) + 1;
+  Local_A11(2,2) := Local_A11(2,2) + 1;
+
+  Put ("Local_A11 :");
+  Dump (Local_A11'Address, Arr11'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A11 : 13 00 ab 00 35 00 cd 00 13 00 ab 00 35 00 cd 00\n" }
+
+  Local_A22(1,1) := Local_A22(1,1) + 1;
+  Local_A22(1,2) := Local_A22(1,2) + 1;
+  Local_A22(2,1) := Local_A22(2,1) + 1;
+  Local_A22(2,2) := Local_A22(2,2) + 1;
+
+  Put ("Local_A22 :");
+  Dump (Local_A22'Address, Arr22'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_A22 : 00 ab 00 13 00 cd 00 35 00 ab 00 13 00 cd 00 35\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/init3.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init3.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init3.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,78 @@
+with System;
+
+package Init3 is
+
+  type Small is mod 2**2;
+  for Small'Size use 2;
+
+  type Count is mod 2**9;
+  for Count'Size use 9;
+
+  type Nested1 is record
+    C1 : Count;
+    C2 : Count;
+    C3 : Count;
+  end record;
+  pragma Pack (Nested1);
+  for Nested1'Size use 27;
+  for Nested1'Bit_Order use System.Low_Order_First;
+  for Nested1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R1 is record
+    S1 : Small;
+    I  : Integer;
+    S2 : Small;
+    N  : Nested1;
+    B  : Boolean;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    S1 at 0 range  0 ..  1;
+    I  at 0 range  2 .. 33;
+    S2 at 0 range 34 .. 35;
+    N  at 0 range 36 .. 62;
+    B  at 0 range 63 .. 63;
+  end record;
+  for R1'Size use 64;
+
+  type Nested2 is record
+    C1 : Count;
+    C2 : Count;
+    C3 : Count;
+  end record;
+  pragma Pack (Nested2);
+  for Nested2'Size use 27;
+  for Nested2'Bit_Order use System.High_Order_First;
+  for Nested2'Scalar_Storage_Order use System.High_Order_First;
+  type R2 is record
+    S1 : Small;
+    I  : Integer;
+    S2 : Small;
+    N  : Nested2;
+    B  : Boolean;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    S1 at 0 range  0 ..  1;
+    I  at 0 range  2 .. 33;
+    S2 at 0 range 34 .. 35;
+    N  at 0 range 36 .. 62;
+    B  at 0 range 63 .. 63;
+  end record;
+  for R2'Size use 64;
+
+  My_R1 : constant R1 := (S1 => 2,
+                          I  => 16#12345678#,
+                          S2 => 1,
+                          N  => (16#AB#, 16#CD#, 16#EF#),
+                          B  => True);
+
+  My_R2 : constant R2 := (S1 => 2,
+                          I  => 16#12345678#,
+                          S2 => 1,
+                          N  => (16#AB#, 16#CD#, 16#EF#),
+                          B  => True);
+
+end Init3;
Index: gcc/testsuite/gnat.dg/sso/init4.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init4.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init4.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,27 @@
+with Ada.Numerics; use Ada.Numerics;
+with System;
+
+package Init4 is
+
+  type R1 is record
+    F : Float;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    F at 0 range 0 .. 31;
+  end record;
+
+  type R2 is record
+    F : Float;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    F at 0 range 0 .. 31;
+  end record;
+
+  My_R1 : constant R1 := (F => Pi);
+  My_R2 : constant R2 := (F => Pi);
+
+end Init4;
Index: gcc/testsuite/gnat.dg/sso/init5.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init5.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init5.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,39 @@
+with System;
+
+package Init5 is
+
+  type Arr1 is array (1 .. 3) of Integer;
+  for Arr1'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R1 is record
+    I : Integer;
+    A : Arr1;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    I at 0 range 0 .. 31;
+    A at 4 range 0 .. 95;
+  end record;
+
+  type Arr2 is array (1 .. 3) of Integer;
+  for Arr2'Scalar_Storage_Order use System.High_Order_First;
+
+  type R2 is record
+    I : Integer;
+    A : Arr2;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    I at 0 range 0 .. 31;
+    A at 4 range 0 .. 95;
+  end record;
+
+  My_R1 : constant R1 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+  My_R2 : constant R2 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+end Init5;
Index: gcc/testsuite/gnat.dg/sso/init6.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init6.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init6.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,39 @@
+with System;
+
+package Init6 is
+
+  type Arr1 is array (1 .. 3) of Integer;
+  for Arr1'Scalar_Storage_Order use System.High_Order_First;
+
+  type R1 is record
+    I : Integer;
+    A : Arr1;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    I at 0 range 0 .. 31;
+    A at 4 range 0 .. 95;
+  end record;
+
+  type Arr2 is array (1 .. 3) of Integer;
+  for Arr2'Scalar_Storage_Order use System.Low_Order_First;
+
+  type R2 is record
+    I : Integer;
+    A : Arr2;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    I at 0 range 0 .. 31;
+    A at 4 range 0 .. 95;
+  end record;
+
+  My_R1 : constant R1 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+  My_R2 : constant R2 := (I => 16#12345678#,
+                          A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+end Init6;
Index: gcc/testsuite/gnat.dg/sso/init7.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init7.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init7.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,59 @@
+with System;
+
+package Init7 is
+
+  type Nested1 is record
+    C1 : Integer;
+    C2 : Integer;
+    C3 : Integer;
+  end record;
+  for Nested1'Bit_Order use System.Low_Order_First;
+  for Nested1'Scalar_Storage_Order use System.Low_Order_First;
+  for Nested1 use record
+    C1 at 0 range 0 .. 31;
+    C2 at 4 range 0 .. 31;
+    C3 at 8 range 0 .. 31;
+  end record;
+
+  type R1 is record
+    I : Integer;
+    N : Nested1;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    I at 0 range 0 .. 31;
+    N at 4 range 0 .. 95;
+  end record;
+
+  type Nested2 is record
+    C1 : Integer;
+    C2 : Integer;
+    C3 : Integer;
+  end record;
+  for Nested2'Bit_Order use System.High_Order_First;
+  for Nested2'Scalar_Storage_Order use System.High_Order_First;
+  for Nested2 use record
+    C1 at 0 range 0 .. 31;
+    C2 at 4 range 0 .. 31;
+    C3 at 8 range 0 .. 31;
+  end record;
+
+  type R2 is record
+    I : Integer;
+    N : Nested2;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    I at 0 range 0 .. 31;
+    N at 4 range 0 .. 95;
+  end record;
+
+  My_R1 : constant R1 := (I => 16#12345678#,
+                          N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+  My_R2 : constant R2 := (I => 16#12345678#,
+                          N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+end Init7;
Index: gcc/testsuite/gnat.dg/sso/init8.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init8.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init8.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,59 @@
+with System;
+
+package Init8 is
+
+  type Nested1 is record
+    C1 : Integer;
+    C2 : Integer;
+    C3 : Integer;
+  end record;
+  for Nested1'Bit_Order use System.High_Order_First;
+  for Nested1'Scalar_Storage_Order use System.High_Order_First;
+  for Nested1 use record
+    C1 at 0 range 0 .. 31;
+    C2 at 4 range 0 .. 31;
+    C3 at 8 range 0 .. 31;
+  end record;
+
+  type R1 is record
+    I : Integer;
+    N : Nested1;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    I at 0 range 0 .. 31;
+    N at 4 range 0 .. 95;
+  end record;
+
+  type Nested2 is record
+    C1 : Integer;
+    C2 : Integer;
+    C3 : Integer;
+  end record;
+  for Nested2'Bit_Order use System.Low_Order_First;
+  for Nested2'Scalar_Storage_Order use System.Low_Order_First;
+  for Nested2 use record
+    C1 at 0 range 0 .. 31;
+    C2 at 4 range 0 .. 31;
+    C3 at 8 range 0 .. 31;
+  end record;
+
+  type R2 is record
+    I : Integer;
+    N : Nested2;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    I at 0 range 0 .. 31;
+    N at 4 range 0 .. 95;
+  end record;
+
+  My_R1 : constant R1 := (I => 16#12345678#,
+                          N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+  My_R2 : constant R2 := (I => 16#12345678#,
+                          N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+
+end Init8;
Index: gcc/testsuite/gnat.dg/sso/init9.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/init9.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/init9.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,27 @@
+with Ada.Numerics; use Ada.Numerics;
+with System;
+
+package Init9 is
+
+  type R1 is record
+    F : Long_Float;
+  end record;
+  for R1'Bit_Order use System.Low_Order_First;
+  for R1'Scalar_Storage_Order use System.Low_Order_First;
+  for R1 use record
+    F at 0 range 0 .. 63;
+  end record;
+
+  type R2 is record
+    F : Long_Float;
+  end record;
+  for R2'Bit_Order use System.High_Order_First;
+  for R2'Scalar_Storage_Order use System.High_Order_First;
+  for R2 use record
+    F at 0 range 0 .. 63;
+  end record;
+
+  My_R1 : constant R1 := (F => Pi);
+  My_R2 : constant R2 := (F => Pi);
+
+end Init9;
Index: gcc/testsuite/gnat.dg/sso/s3.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/s3.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/s3.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,79 @@
+-- { dg-do run }
+
+with Init3; use Init3;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S3 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  N1 : Nested1;
+  N2 : Nested2;
+
+  C1 : Init3.Count;
+  C2 : Init3.Count;
+  C3 : Init3.Count;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  N1 := A1.N;
+  C1 := N1.C1;
+  C2 := N1.C2;
+  C3 := N1.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 171\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 205\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 239\n" }
+
+  N1.C1 := C1;
+  N1.C2 := C2;
+  N1.C3 := C3;
+  A1.N := N1;
+
+  N2 := A2.N;
+  C1 := N2.C1;
+  C2 := N2.C2;
+  C3 := N2.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 171\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 205\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 239\n" }
+
+  N2.C1 := C1;
+  N2.C2 := C2;
+  N2.C3 := C3;
+  A2.N := N2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/s5.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/s5.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/s5.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,78 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S5 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  AA1 : Arr1;
+  AA2 : Arr2;
+
+  C1 : Integer;
+  C2 : Integer;
+  C3 : Integer;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  AA1 := A1.A;
+  C1 := AA1(1);
+  C2 := AA1(2);
+  C3 := AA1(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA1(1) := C1;
+  AA1(2) := C2;
+  AA1(3) := C3;
+  A1.A := AA1;
+
+  AA2 := A2.A;
+  C1 := AA2(1);
+  C2 := AA2(2);
+  C3 := AA2(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA2(1) := C1;
+  AA2(2) := C2;
+  AA2(3) := C3;
+  A2.A := AA2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/s6.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/s6.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/s6.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,79 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S6 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  AA1 : Arr1;
+  AA2 : Arr2;
+
+  C1 : Integer;
+  C2 : Integer;
+  C3 : Integer;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  AA1 := A1.A;
+  C1 := AA1(1);
+  C2 := AA1(2);
+  C3 := AA1(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA1(1) := C1;
+  AA1(2) := C2;
+  AA1(3) := C3;
+  A1.A := AA1;
+
+  AA2 := A2.A;
+  C1 := AA2(1);
+  C2 := AA2(2);
+  C3 := AA2(3);
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  AA2(1) := C1;
+  AA2(2) := C2;
+  AA2(3) := C3;
+  A2.A := AA2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/s7.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/s7.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/s7.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,79 @@
+-- { dg-do run }
+
+with Init7; use Init7;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S7 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  N1 : Nested1;
+  N2 : Nested2;
+
+  C1 : Integer;
+  C2 : Integer;
+  C3 : Integer;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  N1 := A1.N;
+  C1 := N1.C1;
+  C2 := N1.C2;
+  C3 := N1.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  N1.C1 := C1;
+  N1.C2 := C2;
+  N1.C3 := C3;
+  A1.N := N1;
+
+  N2 := A2.N;
+  C1 := N2.C1;
+  C2 := N2.C2;
+  C3 := N2.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  N2.C1 := C1;
+  N2.C2 := C2;
+  N2.C3 := C3;
+  A2.N := N2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/s8.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/s8.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/s8.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,79 @@
+-- { dg-do run }
+
+with Init8; use Init8;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure S8 is
+
+  A1 : R1 := My_R1;
+  A2 : R2 := My_R2;
+
+  N1 : Nested1;
+  N2 : Nested2;
+
+  C1 : Integer;
+  C2 : Integer;
+  C3 : Integer;
+
+begin
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  N1 := A1.N;
+  C1 := N1.C1;
+  C2 := N1.C2;
+  C3 := N1.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  N1.C1 := C1;
+  N1.C2 := C2;
+  N1.C3 := C3;
+  A1.N := N1;
+
+  N2 := A2.N;
+  C1 := N2.C1;
+  C2 := N2.C2;
+  C3 := N2.C3;
+
+  Put_Line("C1 :" & C1'Img);
+  -- { dg-output "C1 : 11206674\n" }
+
+  Put_Line("C2 :" & C2'Img);
+  -- { dg-output "C2 : 13434932\n" }
+
+  Put_Line("C3 :" & C3'Img);
+  -- { dg-output "C3 : 15663190\n" }
+
+  N2.C1 := C1;
+  N2.C2 := C2;
+  N2.C3 := C3;
+  A2.N := N2;
+
+  Put ("A1 :");
+  Dump (A1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Put ("A2 :");
+  Dump (A2'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/dump.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/dump.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/dump.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,17 @@
+-- { dg-do compile }
+
+with Text_IO; use Text_IO;
+
+procedure Dump (A : System.Address; Len : Storage_Offset) is
+
+   Arr : Storage_Array (1 .. Len);
+   for Arr'Address use A;
+   pragma Import (Ada, Arr);
+
+   H : constant array (Storage_Element range 0 .. 15) of Character :=
+         "0123456789abcdef";
+begin
+   for J in Arr'Range loop
+      Put (' ' & H (Arr (J) / 16) & H (Arr (J) mod 16));
+   end loop;
+end;
Index: gcc/testsuite/gnat.dg/sso/sso.exp
===================================================================
--- gcc/testsuite/gnat.dg/sso/sso.exp	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/sso.exp	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,40 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib gnat-dg.exp
+load_lib torture-options.exp
+
+# Initialize `dg'.
+torture-init
+dg-init
+
+set SSO_TORTURE_OPTIONS [list \
+	{ -O0 } \
+	{ -O1 -fno-inline } \
+	{ -O2 } \
+	{ -O3 -finline-functions } \
+	{ -Os } \
+	{ -Og -g } ]
+
+set-torture-options $SSO_TORTURE_OPTIONS
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.adb]] "" ""
+
+# All done.
+dg-finish
+torture-finish
Index: gcc/testsuite/gnat.dg/sso/p1.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p1.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p1.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,62 @@
+-- { dg-do run }
+
+with Init1; use Init1;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P1 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := 16#12345678#;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := 16#12345678#;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := Local_R2.I;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := Local_R1.I;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/p2.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p2.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p2.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,80 @@
+-- { dg-do run }
+
+with Init2; use Init2;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P2 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               A  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               A  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1.S1   := Local_R2.S1;
+  Local_R1.I    := Local_R2.I;
+  Local_R1.S2   := Local_R2.S2;
+  Local_R1.A(1) := Local_R2.A(1);
+  Local_R1.A(2) := Local_R2.A(2);
+  Local_R1.A(3) := Local_R2.A(3);
+  Local_R1.B    := Local_R2.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2.S1   := Local_R1.S1;
+  Local_R2.I    := Local_R1.I;
+  Local_R2.S2   := Local_R1.S2;
+  Local_R2.A(1) := Local_R1.A(1);
+  Local_R2.A(2) := Local_R1.A(2);
+  Local_R2.A(3) := Local_R1.A(3);
+  Local_R2.B    := Local_R1.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/p3.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p3.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p3.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,80 @@
+-- { dg-do run }
+
+with Init3; use Init3;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P3 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               N  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               N  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1.S1   := Local_R2.S1;
+  Local_R1.I    := Local_R2.I;
+  Local_R1.S2   := Local_R2.S2;
+  Local_R1.N.C1 := Local_R2.N.C1;
+  Local_R1.N.C2 := Local_R2.N.C2;
+  Local_R1.N.C3 := Local_R2.N.C3;
+  Local_R1.B    := Local_R2.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2.S1   := Local_R1.S1;
+  Local_R2.I    := Local_R1.I;
+  Local_R2.S2   := Local_R1.S2;
+  Local_R2.N.C1 := Local_R1.N.C1;
+  Local_R2.N.C2 := Local_R1.N.C2;
+  Local_R2.N.C3 := Local_R1.N.C3;
+  Local_R2.B    := Local_R1.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/p4.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p4.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p4.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,63 @@
+-- { dg-do run }
+
+with Init4; use Init4;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P4 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : db 0f 49 40\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 40 49 0f db\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db\n" }
+
+  Local_R1.F := Pi;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40\n" }
+
+  Local_R2.F := Pi;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db\n" }
+
+  Local_R1.F := Local_R2.F;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40\n" }
+
+  Local_R2.F := Local_R1.F;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/p5.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p5.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p5.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,68 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P5 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1.I    := Local_R2.I;
+  Local_R1.A(1) := Local_R2.A(1);
+  Local_R1.A(2) := Local_R2.A(2);
+  Local_R1.A(3) := Local_R2.A(3);
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2.I    := Local_R1.I;
+  Local_R2.A(1) := Local_R1.A(1);
+  Local_R2.A(2) := Local_R1.A(2);
+  Local_R2.A(3) := Local_R1.A(3);
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/t1.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t1.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t1.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,55 @@
+-- { dg-do run }
+
+with Init1; use Init1;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T1 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I := My_R1.I + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12\n" }
+
+  Local_R2.I := My_R2.I + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79\n" }
+
+  Local_R1.I := 16#12345678#;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12\n" }
+
+  Local_R2.I := 16#12345678#;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78\n" }
+
+  Local_R1.I := Local_R1.I + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12\n" }
+
+  Local_R2.I := Local_R2.I + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/p6.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p6.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p6.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,61 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P6 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1.I    := Local_R2.I;
+  Local_R1.A(1) := Local_R2.A(1);
+  Local_R1.A(2) := Local_R2.A(2);
+  Local_R1.A(3) := Local_R2.A(3);
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2.I    := Local_R1.I;
+  Local_R2.A(1) := Local_R1.A(1);
+  Local_R2.A(2) := Local_R1.A(2);
+  Local_R2.A(3) := Local_R1.A(3);
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/t2.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t2.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t2.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,84 @@
+-- { dg-do run }
+
+with Init2; use Init2;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T2 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.S1 := My_R1.S1 - 1;
+  Local_R1.I := My_R1.I + 1;
+  Local_R1.S2 := My_R1.S2 - 1;
+  Local_R1.A(1) := My_R1.A(1) mod 16;
+  Local_R1.A(2) := My_R1.A(2) mod 16;
+  Local_R1.A(3) := My_R1.A(3) mod 16;
+  Local_R1.B := not My_R1.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" }
+
+  Local_R2.S1 := My_R2.S1 - 1;
+  Local_R2.I := My_R2.I + 1;
+  Local_R2.S2 := My_R2.S2 - 1;
+  Local_R2.A(1) := My_R2.A(1) mod 16;
+  Local_R2.A(2) := My_R2.A(2) mod 16;
+  Local_R2.A(3) := My_R2.A(3) mod 16;
+  Local_R2.B := not My_R2.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" }
+
+  Local_R1 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               A  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               A  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1.S1   := Local_R1.S1 - 1;
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.S2   := Local_R1.S2 - 1;
+  Local_R1.A(1) := Local_R1.A(1) mod 16;
+  Local_R1.A(2) := Local_R1.A(2) mod 16;
+  Local_R1.A(3) := Local_R1.A(3) mod 16;
+  Local_R1.B    := not Local_R1.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" }
+
+  Local_R2.S1   := Local_R2.S1 - 1;
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.S2   := Local_R2.S2 - 1;
+  Local_R2.A(1) := Local_R2.A(1) mod 16;
+  Local_R2.A(2) := Local_R2.A(2) mod 16;
+  Local_R2.A(3) := Local_R2.A(3) mod 16;
+  Local_R2.B    := not Local_R2.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/p7.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p7.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p7.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,61 @@
+-- { dg-do run }
+
+with Init7; use Init7;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P7 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R1 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R2 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R1.I    := Local_R2.I;
+  Local_R1.N.C1 := Local_R2.N.C1;
+  Local_R1.N.C2 := Local_R2.N.C2;
+  Local_R1.N.C3 := Local_R2.N.C3;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R2.I    := Local_R1.I;
+  Local_R2.N.C1 := Local_R1.N.C1;
+  Local_R2.N.C2 := Local_R1.N.C2;
+  Local_R2.N.C3 := Local_R1.N.C3;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/dump.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso/dump.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/dump.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,3 @@
+with System.Storage_Elements; use System.Storage_Elements;
+
+procedure Dump (A : System.Address; Len : Storage_Offset);
Index: gcc/testsuite/gnat.dg/sso/t3.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t3.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t3.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,84 @@
+-- { dg-do run }
+
+with Init3; use Init3;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T3 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.S1   := My_R1.S1 - 1;
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.S2   := My_R1.S2 - 1;
+  Local_R1.N.C1 := My_R1.N.C1 mod 16;
+  Local_R1.N.C2 := My_R1.N.C2 mod 16;
+  Local_R1.N.C3 := My_R1.N.C3 mod 16;
+  Local_R1.B    := not My_R1.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" }
+
+  Local_R2.S1   := My_R2.S1 - 1;
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.S2   := My_R2.S2 - 1;
+  Local_R2.N.C1 := My_R2.N.C1 mod 16;
+  Local_R2.N.C2 := My_R2.N.C2 mod 16;
+  Local_R2.N.C3 := My_R2.N.C3 mod 16;
+  Local_R2.B    := not My_R2.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" }
+
+  Local_R1 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               N  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" }
+
+  Local_R2 := (S1 => 2,
+               I  => 16#12345678#,
+               S2 => 1,
+               N  => (16#AB#, 16#CD#, 16#EF#),
+               B  => True);
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" }
+
+  Local_R1.S1   := Local_R1.S1 - 1;
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.S2   := Local_R1.S2 - 1;
+  Local_R1.N.C1 := Local_R1.N.C1 mod 16;
+  Local_R1.N.C2 := Local_R1.N.C2 mod 16;
+  Local_R1.N.C3 := Local_R1.N.C3 mod 16;
+  Local_R1.B    := not Local_R1.B;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" }
+
+  Local_R2.S1   := Local_R2.S1 - 1;
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.S2   := Local_R2.S2 - 1;
+  Local_R2.N.C1 := Local_R2.N.C1 mod 16;
+  Local_R2.N.C2 := Local_R2.N.C2 mod 16;
+  Local_R2.N.C3 := Local_R2.N.C3 mod 16;
+  Local_R2.B    := not Local_R2.B;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/t4.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t4.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t4.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,56 @@
+-- { dg-do run }
+
+with Init4; use Init4;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T4 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.F := My_R1.F + 1.0;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : ee 87 84 40\n" }
+
+  Local_R2.F := My_R2.F + 1.0;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 84 87 ee\n" }
+
+  Local_R1.F := Pi;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : db 0f 49 40\n" }
+
+  Local_R2.F := Pi;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 49 0f db\n" }
+
+  Local_R1.F := Local_R1.F + 1.0;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : ee 87 84 40\n" }
+
+  Local_R2.F := Local_R2.F + 1.0;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 84 87 ee\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/p8.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p8.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p8.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,61 @@
+-- { dg-do run }
+
+with Init8; use Init8;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P8 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2 := (I => 16#12345678#,
+               N => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+  Local_R1.I    := Local_R2.I;
+  Local_R1.N.C1 := Local_R2.N.C1;
+  Local_R1.N.C2 := Local_R2.N.C2;
+  Local_R1.N.C3 := Local_R2.N.C3;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+  Local_R2.I    := Local_R1.I;
+  Local_R2.N.C1 := Local_R1.N.C1;
+  Local_R2.N.C2 := Local_R1.N.C2;
+  Local_R2.N.C3 := Local_R1.N.C3;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/t5.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t5.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t5.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,67 @@
+-- { dg-do run }
+
+with Init5; use Init5;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T5 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.A(1) := My_R1.A(1) + 1;
+  Local_R1.A(2) := My_R1.A(2) + 1;
+  Local_R1.A(3) := My_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.A(1) := My_R2.A(1) + 1;
+  Local_R2.A(2) := My_R2.A(2) + 1;
+  Local_R2.A(3) := My_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.A(1) := Local_R1.A(1) + 1;
+  Local_R1.A(2) := Local_R1.A(2) + 1;
+  Local_R1.A(3) := Local_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.A(1) := Local_R2.A(1) + 1;
+  Local_R2.A(2) := Local_R2.A(2) + 1;
+  Local_R2.A(3) := Local_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso/p9.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/p9.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/p9.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,63 @@
+-- { dg-do run }
+
+with Init9; use Init9;
+with Ada.Numerics; use Ada.Numerics;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure P9 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Put ("My_R1    :");
+  Dump (My_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R1    : 18 2d 44 54 fb 21 09 40\n" }
+
+  Put ("My_R2    :");
+  Dump (My_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "My_R2    : 40 09 21 fb 54 44 2d 18\n" }
+
+  Local_R1 := My_R1;
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Local_R2 := My_R2;
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" }
+
+  Local_R1.F := Pi;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Local_R2.F := Pi;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" }
+
+  Local_R1.F := Local_R2.F;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" }
+
+  Local_R2.F := Local_R1.F;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" }
+end;
Index: gcc/testsuite/gnat.dg/sso/t6.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso/t6.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso/t6.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,67 @@
+-- { dg-do run }
+
+with Init6; use Init6;
+with Text_IO; use Text_IO;
+with Dump;
+
+procedure T6 is
+
+  Local_R1 : R1;
+  Local_R2 : R2;
+
+begin
+  Local_R1.I    := My_R1.I + 1;
+  Local_R1.A(1) := My_R1.A(1) + 1;
+  Local_R1.A(2) := My_R1.A(2) + 1;
+  Local_R1.A(3) := My_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R2.I    := My_R2.I + 1;
+  Local_R2.A(1) := My_R2.A(1) + 1;
+  Local_R2.A(2) := My_R2.A(2) + 1;
+  Local_R2.A(3) := My_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+  Local_R1 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" }
+
+  Local_R2 := (I => 16#12345678#,
+               A => (16#AB0012#, 16#CD0034#, 16#EF0056#));
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" }
+
+  Local_R1.I    := Local_R1.I + 1;
+  Local_R1.A(1) := Local_R1.A(1) + 1;
+  Local_R1.A(2) := Local_R1.A(2) + 1;
+  Local_R1.A(3) := Local_R1.A(3) + 1;
+
+  Put ("Local_R1 :");
+  Dump (Local_R1'Address, R1'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" }
+
+  Local_R2.I    := Local_R2.I + 1;
+  Local_R2.A(1) := Local_R2.A(1) + 1;
+  Local_R2.A(2) := Local_R2.A(2) + 1;
+  Local_R2.A(3) := Local_R2.A(3) + 1;
+
+  Put ("Local_R2 :");
+  Dump (Local_R2'Address, R2'Max_Size_In_Storage_Elements);
+  New_Line;
+  -- { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" }
+
+end;
Index: gcc/testsuite/gnat.dg/sso7.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso7.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso7.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,52 @@
+-- { dg-do run }
+
+with System;
+
+procedure SSO7 is
+
+   type Short_Int is mod 2**16;
+
+   type Rec1 is record
+      F1 : Short_Int;
+      F2 : Short_Int;
+   end record;
+   for Rec1 use record
+      F1 at 0 range  0 .. 15;
+      F2 at 0 range 16 .. 31;
+   end record;
+   for Rec1'Bit_Order use System.High_Order_First;
+   for Rec1'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec2 is record
+      R1 : Rec1;
+   end record;
+   for Rec2 use record
+      R1 at 0 range 0 .. 31;
+   end record;
+   for Rec2'Bit_Order use System.High_Order_First;
+   for Rec2'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec3 is record
+      Data : Rec1;
+   end record;
+   for Rec3 use record
+      Data at 0 range 1 .. 32;
+   end record;
+   for Rec3'Bit_Order use System.High_Order_First;
+   for Rec3'Scalar_Storage_Order use System.High_Order_First;
+
+   procedure Copy (Message : in Rec3) is
+      Local : Rec2;
+   begin
+      Local := (R1 => Message.Data);
+      if Local.R1 /= Message.Data then
+         raise Program_Error;
+      end if;
+   end;
+
+   Message : Rec3;
+
+begin
+   Message := (Data => (2, 3));
+   Copy(Message);
+end;
Index: gcc/testsuite/gnat.dg/sso1.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso1.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso1.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,77 @@
+-- { dg-do run }
+
+with System;
+with Ada.Unchecked_Conversion;
+with Ada.Streams; use Ada.Streams;
+with Ada.Text_IO;
+
+procedure SSO1 is
+
+   type Unsigned_Integer_4 is mod 2 ** 32;
+   for Unsigned_Integer_4'Size use 32;
+
+   Default_Bit_Order_Pos : constant Natural := System.Bit_Order'Pos (System.Default_Bit_Order);
+
+   Opposite_Bit_Order_Pos : constant Natural := 1 - Default_Bit_Order_Pos;
+
+   Opposite_Bit_Order : constant System.Bit_Order := System.Bit_Order'Val (Opposite_Bit_Order_Pos);
+
+   type Rec is
+      record
+	 X, Y : Unsigned_Integer_4;
+      end record;
+   for Rec'Bit_Order use System.Default_Bit_Order;
+   for Rec'Scalar_Storage_Order use System.Default_Bit_Order;
+
+   for Rec use
+      record
+	 X at 0 * 4 range 0 .. 31;
+	 Y at 1 * 4 range 0 .. 31;
+      end record;
+   
+   type Nested_Rec is
+      record 
+	 I : Unsigned_Integer_4;
+	 R : Rec;
+	 J : Unsigned_Integer_4;
+      end record;
+   for Nested_Rec use
+      record
+	 I at 0 * 4 range 0 .. 31;
+	 R at 1 * 4 range 0 .. 63;
+	 J at 3 * 4 range 0 .. 31;
+	 end record;
+
+   for Nested_Rec'Bit_Order use Opposite_Bit_Order;
+   for Nested_Rec'Scalar_Storage_Order use Opposite_Bit_Order;
+
+   Nr : Nested_Rec 
+     := (I => 1,
+	 R => (X => 1,
+	       Y => 1),
+	 J => 1);
+   
+   subtype Nested_Rec_As_Stream is Ada.Streams.Stream_Element_Array (1 ..16);
+
+   function To_Stream is
+     new Ada.Unchecked_Conversion (Nested_Rec, Nested_Rec_As_Stream);
+
+   Nr_Stream : constant Nested_Rec_As_Stream := To_Stream (Nr);
+
+   Expected : constant array (System.Bit_Order) of Nested_Rec_As_Stream :=
+                (System.Low_Order_First =>
+                   (0, 0, 0, 1,
+                    1, 0, 0, 0,
+                    1, 0, 0, 0,
+                    0, 0, 0, 1),
+                 System.High_Order_First =>
+                   (1, 0, 0, 0,
+                    0, 0, 0, 1,
+                    0, 0, 0, 1,
+                    1, 0, 0, 0));
+
+begin
+   if Nr_Stream /= Expected (System.Default_Bit_Order) then
+      raise Program_Error;
+   end if;
+end;
Index: gcc/testsuite/gnat.dg/sso2.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso2.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso2.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,14 @@
+-- { dg-do compile }
+
+with Ada.Unchecked_Conversion;
+
+package body SSO2 is
+
+  function Conv is new Ada.Unchecked_Conversion (Arr1, Arr2);
+
+  procedure Proc (A1 : Arr1; A2 : out Arr2) is
+  begin
+     A2 := Conv (A1);
+  end;
+
+end SSO2;
Index: gcc/testsuite/gnat.dg/sso2.ads
===================================================================
--- gcc/testsuite/gnat.dg/sso2.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso2.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,13 @@
+with System;
+
+package SSO2 is
+
+  type Arr1 is array (1 .. 4) of Character;
+  for Arr1'Scalar_Storage_Order use System.High_Order_First;
+
+  type Arr2 is array (1 .. 4) of Character;
+  for Arr2'Scalar_Storage_Order use System.Low_Order_First;
+
+  procedure Proc (A1 : Arr1; A2 : out Arr2);
+
+end SSO2;
Index: gcc/testsuite/gnat.dg/sso3.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso3.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso3.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,52 @@
+-- { dg-do run }
+
+with System; use System;
+
+procedure SSO3 is
+   Rev_SSO : constant Bit_Order
+     := Bit_Order'Val (1 - Bit_Order'Pos (Default_Bit_Order));
+
+   type R (D : Integer) is record
+      Common : Integer;
+      case D is
+         when 0 =>
+            V1 : Integer;
+         when others =>
+            V2 : Integer;
+      end case;
+   end record;
+
+   for R use record
+      D at 0 range 0 .. 31;
+      V1 at 4 range 0 .. 31;
+      V2 at 4 range 0 .. 31;
+      Common at 8 range 0 .. 31;
+   end record;
+   for R'Scalar_Storage_Order use Rev_SSO;
+   for R'Bit_Order use Rev_SSO;
+
+   procedure Check (Common, V : Integer; X : R) is
+   begin
+      if Common /= X.Common then
+         raise Program_Error;
+      end if;
+
+      case X.D is
+         when 0 =>
+            if V /= X.V1 then
+               raise Program_Error;
+            end if;
+         when others =>
+            if V /= X.V2 then
+               raise Program_Error;
+            end if;
+      end case;
+   end Check;
+
+   X0 : R := (D => 0,     Common => 1111, V1 => 1234);
+   X1 : R := (D => 31337, Common => 2222, V2 => 5678);
+
+begin
+   Check (1111, 1234, X0);
+   Check (2222, 5678, X1);
+end;
Index: gcc/testsuite/gnat.dg/sso4.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso4.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso4.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,55 @@
+-- { dg-do run }
+
+with System;
+
+procedure SSO4 is
+
+   type Short_Int is mod 2**16;
+
+   type Rec1 is record
+      F1 : Short_Int;
+      F2 : Short_Int;
+   end record;
+   for Rec1 use record
+      F1 at 0 range  0 .. 15;
+      F2 at 0 range 16 .. 31;
+   end record;
+
+   for Rec1'Bit_Order use System.High_Order_First;
+   for Rec1'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec2 is record
+      I1 : Integer;
+      R1 : Rec1;
+   end record;
+   for Rec2 use record
+      I1 at 0 range 0 .. 31; 
+      R1 at 4 range 0 .. 31;
+   end record;
+   for Rec2'Bit_Order use System.High_Order_First;
+   for Rec2'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec3 is record
+      Data : Rec1;
+   end record;
+   for Rec3 use record
+      Data at 0 range  0 .. 31;
+   end record;
+   for Rec3'Bit_Order use System.High_Order_First;
+   for Rec3'Scalar_Storage_Order use System.High_Order_First;
+
+   procedure Copy (Message : in Rec3) is
+      Local : Rec2;
+   begin
+      Local := (I1 => 1, R1 => Message.Data);
+      if Local.R1 /= Message.Data then
+         raise Program_Error;
+      end if;
+   end;
+
+   Message : Rec3;
+
+begin
+   Message := (Data => (2, 3));
+   Copy(Message);
+end;
Index: gcc/testsuite/gnat.dg/specs/sso2.ads
===================================================================
--- gcc/testsuite/gnat.dg/specs/sso2.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/specs/sso2.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,26 @@
+-- { dg-do compile }
+-- { dg-options "-gnatws" }
+
+with System;
+
+package SSO2 is
+
+  I : Integer;
+
+  type Rec1 is record
+    A : System.Address;
+  end record;
+  for Rec1'Bit_Order use System.High_Order_First;
+  for Rec1'Scalar_Storage_Order use System.High_Order_First;
+
+  R1 : Rec1 := (A => I'Address);
+
+  type Rec2 is record
+    A : System.Address;
+  end record;
+  for Rec2'Bit_Order use System.Low_Order_First;
+  for Rec2'Scalar_Storage_Order use System.Low_Order_First;
+
+  R2 : Rec2 := (A => I'Address);
+
+end SSO2;
Index: gcc/testsuite/gnat.dg/specs/sso1.ads
===================================================================
--- gcc/testsuite/gnat.dg/specs/sso1.ads	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/specs/sso1.ads	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,22 @@
+-- { dg-do compile }
+
+with System;
+
+package SSO1 is
+
+   type R is record  -- { dg-error "inconsistent with bit order" }
+      B : Boolean;
+   end record;
+   for R'Bit_Order use System.Low_Order_First;
+   for R'Scalar_Storage_Order use System.High_Order_First;
+   for R use record
+      B at 0 range 0 .. 1;
+   end record;
+
+   type RW is record
+      B : Boolean;
+   end record;
+   for RW'Bit_Order use System.Low_Order_First;
+   for RW'Scalar_Storage_Order use System.Low_Order_First;  -- { dg-warning "no component clause" }
+
+end SSO1;
Index: gcc/testsuite/gnat.dg/sso5.adb
===================================================================
--- gcc/testsuite/gnat.dg/sso5.adb	(.../trunk)	(revision 0)
+++ gcc/testsuite/gnat.dg/sso5.adb	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,52 @@
+-- { dg-do run }
+
+with System;
+
+procedure SSO5 is
+
+   type Short_Int is mod 2**16;
+
+   type Rec1 is record
+      F1 : Short_Int;
+      F2 : Short_Int;
+   end record;
+   for Rec1 use record
+      F1 at 0 range  0 .. 15;
+      F2 at 0 range 16 .. 31;
+   end record;
+   for Rec1'Bit_Order use System.High_Order_First;
+   for Rec1'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec2 is record
+      R1 : Rec1;
+   end record;
+   for Rec2 use record
+      R1 at 0 range 1 .. 32;
+   end record;
+   for Rec2'Bit_Order use System.High_Order_First;
+   for Rec2'Scalar_Storage_Order use System.High_Order_First;
+
+   type Rec3 is record
+      Data : Rec1;
+   end record;
+   for Rec3 use record
+      Data at 0 range 0 .. 31;
+   end record;
+   for Rec3'Bit_Order use System.High_Order_First;
+   for Rec3'Scalar_Storage_Order use System.High_Order_First;
+
+   procedure Copy (Message : in Rec3) is
+      Local : Rec2;
+   begin
+      Local := (R1 => Message.Data);
+      if Local.R1 /= Message.Data then
+         raise Program_Error;
+      end if;
+   end;
+
+   Message : Rec3;
+
+begin
+   Message := (Data => (2, 3));
+   Copy(Message);
+end;
Index: gcc/testsuite/gcc.dg/sso/sso.exp
===================================================================
--- gcc/testsuite/gcc.dg/sso/sso.exp	(.../trunk)	(revision 0)
+++ gcc/testsuite/gcc.dg/sso/sso.exp	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,40 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib gcc-dg.exp
+load_lib torture-options.exp
+
+# Initialize `dg'.
+torture-init
+dg-init
+
+set SSO_TORTURE_OPTIONS [list \
+	{ -O0 } \
+	{ -O1 -fno-inline } \
+	{ -O2 } \
+	{ -O3 -finline-functions } \
+	{ -Os } \
+	{ -Og -g } ]
+
+set-torture-options $SSO_TORTURE_OPTIONS
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/sso/*.c]] "" ""
+
+# All done.
+dg-finish
+torture-finish
Index: gcc/testsuite/gcc.dg/sso-1.c
===================================================================
--- gcc/testsuite/gcc.dg/sso-1.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/gcc.dg/sso-1.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+int i;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+struct __attribute__((scalar_storage_order("big-endian"))) Rec
+{
+  int *p;
+};
+#else
+struct __attribute__((scalar_storage_order("little-endian"))) Rec
+{
+  int *p;
+};
+#endif
+
+struct Rec r = { &i };  /* { dg-error "element is not constant" } */
Index: gcc/testsuite/g++.dg/sso/sso.exp
===================================================================
--- gcc/testsuite/g++.dg/sso/sso.exp	(.../trunk)	(revision 0)
+++ gcc/testsuite/g++.dg/sso/sso.exp	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,40 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib g++-dg.exp
+load_lib torture-options.exp
+
+# Initialize `dg'.
+torture-init
+dg-init
+
+set SSO_TORTURE_OPTIONS [list \
+	{ -O0 } \
+	{ -O1 -fno-inline } \
+	{ -O2 } \
+	{ -O3 -finline-functions } \
+	{ -Os } \
+	{ -Og -g } ]
+
+set-torture-options $SSO_TORTURE_OPTIONS
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/sso/*.c]] "" ""
+
+# All done.
+dg-finish
+torture-finish
Index: gcc/testsuite/g++.dg/sso-1.C
===================================================================
--- gcc/testsuite/g++.dg/sso-1.C	(.../trunk)	(revision 0)
+++ gcc/testsuite/g++.dg/sso-1.C	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,17 @@
+// { dg-do compile }
+
+int i;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+struct __attribute__((scalar_storage_order("big-endian"))) Rec
+{
+  int *p;
+};
+#else
+struct __attribute__((scalar_storage_order("little-endian"))) Rec
+{
+  int *p;
+};
+#endif
+
+struct Rec r = { &i };
Index: gcc/testsuite/c-c++-common/sso/init6.h
===================================================================
--- gcc/testsuite/c-c++-common/sso/init6.h	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/init6.h	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,24 @@
+struct __attribute__((scalar_storage_order("big-endian"))) Nested1
+{
+  int A[3];
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  int I;
+  struct Nested1 N;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) Nested2
+{
+  int A[3];
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  int I;
+  struct Nested2 N;
+};
+
+struct R1 My_R1 = { 0x12345678, { { 0xAB0012, 0xCD0034, 0xEF0056 } } };
+struct R2 My_R2 = { 0x12345678, { { 0xAB0012, 0xCD0034, 0xEF0056 } } };
Index: gcc/testsuite/c-c++-common/sso/init7.h
===================================================================
--- gcc/testsuite/c-c++-common/sso/init7.h	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/init7.h	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,28 @@
+struct __attribute__((scalar_storage_order("little-endian"))) Nested1
+{
+  int C1;
+  int C2;
+  int C3;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  int I;
+  struct Nested1 N;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) Nested2
+{
+  int C1;
+  int C2;
+  int C3;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  int I;
+  struct Nested2 N;
+};
+
+struct R1 My_R1 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
+struct R2 My_R2 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
Index: gcc/testsuite/c-c++-common/sso/init8.h
===================================================================
--- gcc/testsuite/c-c++-common/sso/init8.h	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/init8.h	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,28 @@
+struct __attribute__((scalar_storage_order("big-endian"))) Nested1
+{
+  int C1;
+  int C2;
+  int C3;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  int I;
+  struct Nested1 N;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) Nested2
+{
+  int C1;
+  int C2;
+  int C3;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  int I;
+  struct Nested2 N;
+};
+
+struct R1 My_R1 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
+struct R2 My_R2 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
Index: gcc/testsuite/c-c++-common/sso/init9.h
===================================================================
--- gcc/testsuite/c-c++-common/sso/init9.h	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/init9.h	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,14 @@
+#define Pi 3.14159265358979323846
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  double F;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  double F;
+};
+
+struct R1 My_R1 = { Pi };
+struct R2 My_R2 = { Pi };
Index: gcc/testsuite/c-c++-common/sso/q1.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/q1.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/q1.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init1.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 78 56 34 12\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 12 34 56 78\n" } */
+
+  if (A1.I != B1.I) abort ();
+
+  if (A1.I != 0x12345678) abort ();
+
+  if (A2.I != B2.I) abort ();
+
+  if (A2.I != 0x12345678) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/q2.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/q2.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/q2.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,54 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init2.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  if (A1.S1 != B1.S1) abort ();
+
+  if (A1.S1 != 2) abort ();
+
+  if (A2.S1 != B2.S1) abort ();
+
+  if (A2.S1 != 2) abort ();
+
+  if (A1.I != B1.I || A1.A1 != B1.A1) abort ();
+
+  if (A2.I != B2.I || A2.A1 != B2.A1) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/q3.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/q3.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/q3.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,54 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init3.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  if (A1.S1 != B1.S1) abort ();
+
+  if (A1.S1 != 2) abort ();
+
+  if (A2.S1 != B2.S1) abort ();
+
+  if (A2.S1 != 2) abort ();
+
+  if (A1.I != B1.I || A1.N.C1 != B1.N.C1) abort ();
+
+  if (A2.I != B2.I || A2.N.C1 != B2.N.C1) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/q4.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/q4.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/q4.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init4.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : db 0f 49 40\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : db 0f 49 40\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 40 49 0f db\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 40 49 0f db\n" } */
+
+  if (A1.F != B1.F) abort ();
+
+  if (A1.F != Pi) abort ();
+
+  if (A2.F != B2.F) abort ();
+
+  if (A2.F != Pi) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/q5.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/q5.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/q5.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  if (A1.I != B1.I || A1.A[0] != B1.A[0]) abort();
+
+  if (A2.I != B2.I || A2.A[0] != B2.A[0]) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/s3.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/s3.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/s3.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,79 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init3.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  struct Nested1 N1;
+  struct Nested2 N2;
+
+  unsigned C1;
+  unsigned C2;
+  unsigned C3;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  N1 = A1.N;
+  C1 = N1.C1;
+  C2 = N1.C2;
+  C3 = N1.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 18\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 52\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 86\n" } */
+
+  N1.C1 = C1;
+  N1.C2 = C2;
+  N1.C3 = C3;
+  A1.N = N1;
+
+  N2 = A2.N;
+  C1 = N2.C1;
+  C2 = N2.C2;
+  C3 = N2.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 18\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 52\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 86\n" } */
+
+  N2.C1 = C1;
+  N2.C2 = C2;
+  N2.C3 = C3;
+  A2.N = N2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/q6.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/q6.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/q6.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  if (A1.I != B1.I || A1.N.A[0] != B1.N.A[0]) abort();
+
+  if (A2.I != B2.I || A2.N.A[0] != B2.N.A[0]) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/q7.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/q7.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/q7.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init7.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  if (A1.I != B1.I || A1.N.C1 != B1.N.C1) abort();
+
+  if (A2.I != B2.I || A2.N.C1 != B2.N.C1) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/s5.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/s5.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/s5.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,91 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+#pragma GCC diagnostic ignored "-Wscalar-storage-order"
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  struct __attribute__((scalar_storage_order("little-endian"))) Nested1
+  {
+    int A[3];
+  };
+
+  struct __attribute__((scalar_storage_order("big-endian"))) Nested2
+  {
+    int A[3];
+  };
+
+  struct Nested1 N1;
+  struct Nested2 N2;
+
+  int C1;
+  int C2;
+  int C3;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  __builtin_memcpy (N1.A, A1.A, sizeof (int) * 3);
+  C1 = N1.A[0];
+  C2 = N1.A[1];
+  C3 = N1.A[2];
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N1.A[0] = C1;
+  N1.A[1] = C2;
+  N1.A[2] = C3;
+  __builtin_memcpy (A1.A, N1.A, sizeof (int) * 3);
+
+  __builtin_memcpy (N2.A, A2.A, sizeof (int) * 3);
+  C1 = N2.A[0];
+  C2 = N2.A[1];
+  C3 = N2.A[2];
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N2.A[0] = C1;
+  N2.A[1] = C2;
+  N2.A[2] = C3;
+  __builtin_memcpy (A2.A, N2.A, sizeof (int) * 3);
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/q8.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/q8.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/q8.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init8.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  if (A1.I != B1.I || A1.N.C1 != B1.N.C1) abort();
+
+  if (A2.I != B2.I || A2.N.C1 != B2.N.C1) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/s6.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/s6.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/s6.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,81 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+#pragma GCC diagnostic ignored "-Wscalar-storage-order"
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  struct Nested1 N1;
+  struct Nested2 N2;
+
+  int C1;
+  int C2;
+  int C3;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  __builtin_memcpy (N1.A, A1.N.A, sizeof (int) * 3);
+  C1 = N1.A[0];
+  C2 = N1.A[1];
+  C3 = N1.A[2];
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N1.A[0] = C1;
+  N1.A[1] = C2;
+  N1.A[2] = C3;
+  __builtin_memcpy (A1.N.A, N1.A, sizeof (int) * 3);
+
+  __builtin_memcpy (N2.A, A2.N.A, sizeof (int) * 3);
+  C1 = N2.A[0];
+  C2 = N2.A[1];
+  C3 = N2.A[2];
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N2.A[0] = C1;
+  N2.A[1] = C2;
+  N2.A[2] = C3;
+  __builtin_memcpy (A2.N.A, N2.A, sizeof (int) * 3);
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/u5.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/u5.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/u5.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+  int C1;
+  int C2;
+
+  Local_R1.I    = 1;
+  Local_R1.A[0] = 0xAB0012;
+  Local_R1.A[1] = 0xCD0034;
+  Local_R1.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 01 00 00 00 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = 1;
+  Local_R2.A[0] = 0xAB0012;
+  Local_R2.A[1] = 0xCD0034;
+  Local_R2.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 00 00 00 01 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  C1 = Local_R1.A[Local_R1.I];
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 13434932\n" } */
+
+  Local_R1.I++;
+  C1 = Local_R1.A[Local_R1.I];
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 15663190\n" } */
+
+  C2 = Local_R2.A[Local_R2.I];
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  Local_R2.I++;
+  C2 = Local_R2.A[Local_R2.I];
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 15663190\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/s7.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/s7.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/s7.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,79 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init7.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  struct Nested1 N1;
+  struct Nested2 N2;
+
+  int C1;
+  int C2;
+  int C3;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  N1 = A1.N;
+  C1 = N1.C1;
+  C2 = N1.C2;
+  C3 = N1.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N1.C1 = C1;
+  N1.C2 = C2;
+  N1.C3 = C3;
+  A1.N = N1;
+
+  N2 = A2.N;
+  C1 = N2.C1;
+  C2 = N2.C2;
+  C3 = N2.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N2.C1 = C1;
+  N2.C2 = C2;
+  N2.C3 = C3;
+  A2.N = N2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/q9.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/q9.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/q9.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init9.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R1 B1 = My_R1;
+
+  struct R2 A2 = My_R2;
+  struct R2 B2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  put ("B1 :");
+  dump (&B1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "B1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  put ("B2 :");
+  dump (&B2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "B2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  if (A1.F != B1.F) abort ();
+
+  if (A1.F != Pi) abort ();
+
+  if (A2.F != B2.F) abort ();
+
+  if (A2.F != Pi) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/u6.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/u6.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/u6.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+  int C1;
+  int C2;
+
+  Local_R1.I      = 1;
+  Local_R1.N.A[0] = 0xAB0012;
+  Local_R1.N.A[1] = 0xCD0034;
+  Local_R1.N.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 01 00 00 00 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I      = 1;
+  Local_R2.N.A[0] = 0xAB0012;
+  Local_R2.N.A[1] = 0xCD0034;
+  Local_R2.N.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 00 00 00 01 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  C1 = Local_R1.N.A[Local_R1.I];
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 13434932\n" } */
+
+  Local_R1.I++;
+  C1 = Local_R1.N.A[Local_R1.I];
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 15663190\n" } */
+
+  C2 = Local_R2.N.A[Local_R2.I];
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  Local_R2.I++;
+  C2 = Local_R2.N.A[Local_R2.I];
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 15663190\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/s8.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/s8.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/s8.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,79 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init8.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  struct Nested1 N1;
+  struct Nested2 N2;
+
+  int C1;
+  int C2;
+  int C3;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  N1 = A1.N;
+  C1 = N1.C1;
+  C2 = N1.C2;
+  C3 = N1.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N1.C1 = C1;
+  N1.C2 = C2;
+  N1.C3 = C3;
+  A1.N = N1;
+
+  N2 = A2.N;
+  C1 = N2.C1;
+  C2 = N2.C2;
+  C3 = N2.C3;
+
+  printf ("C1 : %d\n", C1);
+  /* { dg-output "C1 : 11206674\n" } */
+
+  printf ("C2 : %d\n", C2);
+  /* { dg-output "C2 : 13434932\n" } */
+
+  printf ("C3 : %d\n", C3);
+  /* { dg-output "C3 : 15663190\n" } */
+
+  N2.C1 = C1;
+  N2.C2 = C2;
+  N2.C3 = C3;
+  A2.N = N2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/dump.h
===================================================================
--- gcc/testsuite/c-c++-common/sso/dump.h	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/dump.h	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,23 @@
+void dump (void *p, unsigned int len)
+{
+  const char digits[17] = "0123456789abcdef";
+  unsigned char *a = (unsigned char *)p;
+  int i;
+
+  for (i = 0; i < len; i++)
+    {
+      putchar (' ');
+      putchar (digits[a[i] / 16]);
+      putchar (digits[a[i] % 16]);
+    }
+}
+
+void put (const char s[])
+{
+  fputs (s, stdout);
+}
+
+void new_line (void)
+{
+  putchar ('\n');
+}
Index: gcc/testsuite/c-c++-common/sso/p1.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/p1.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/p1.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,64 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init1.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 78 56 34 12\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 12 34 56 78\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78\n" } */
+
+  Local_R1.I = 0x12345678;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12\n" } */
+
+  Local_R2.I = 0x12345678;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78\n" } */
+
+  Local_R1.I = Local_R2.I;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12\n" } */
+
+  Local_R2.I = Local_R1.I;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/p2.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/p2.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/p2.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,88 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init2.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  Local_R1.S1 = 2;
+  Local_R1.I  = 0x12345678;
+  Local_R1.S2 = 1;
+  Local_R1.A1 = 0xAB;
+  Local_R1.A2 = 0xCD;
+  Local_R1.A3 = 0xEF;
+  Local_R1.B  = 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  Local_R2.S1 = 2;
+  Local_R2.I  = 0x12345678;
+  Local_R2.S2 = 1;
+  Local_R2.A1 = 0xAB;
+  Local_R2.A2 = 0xCD;
+  Local_R2.A3 = 0xEF;
+  Local_R2.B  = 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  Local_R1.S1 = Local_R2.S1;
+  Local_R1.I  = Local_R2.I;
+  Local_R1.S2 = Local_R2.S2;
+  Local_R1.A1 = Local_R2.A1;
+  Local_R1.A2 = Local_R2.A2;
+  Local_R1.A3 = Local_R2.A3;
+  Local_R1.B  = Local_R2.B;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  Local_R2.S1 = Local_R1.S1;
+  Local_R2.I  = Local_R1.I;
+  Local_R2.S2 = Local_R1.S2;
+  Local_R2.A1 = Local_R1.A1;
+  Local_R2.A2 = Local_R1.A2;
+  Local_R2.A3 = Local_R1.A3;
+  Local_R2.B  = Local_R1.B;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/p3.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/p3.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/p3.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,88 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init3.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  Local_R1.S1   = 2;
+  Local_R1.I    = 0x78ABCDEF;
+  Local_R1.S2   = 1;
+  Local_R1.N.C1 = 0x12;
+  Local_R1.N.C2 = 0x34;
+  Local_R1.N.C3 = 0x56;
+  Local_R1.N.B  = 4;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  Local_R2.S1   = 2;
+  Local_R2.I    = 0x78ABCDEF;
+  Local_R2.S2   = 1;
+  Local_R2.N.C1 = 0x12;
+  Local_R2.N.C2 = 0x34;
+  Local_R2.N.C3 = 0x56;
+  Local_R2.N.B  = 4;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  Local_R1.S1   = Local_R2.S1;
+  Local_R1.I    = Local_R2.I;
+  Local_R1.S2   = Local_R2.S2;
+  Local_R1.N.C1 = Local_R2.N.C1;
+  Local_R1.N.C2 = Local_R2.N.C2;
+  Local_R1.N.C3 = Local_R2.N.C3;
+  Local_R1.N.B  = Local_R2.N.B;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  Local_R2.S1   = Local_R1.S1;
+  Local_R2.I    = Local_R1.I;
+  Local_R2.S2   = Local_R1.S2;
+  Local_R2.N.C1 = Local_R1.N.C1;
+  Local_R2.N.C2 = Local_R1.N.C2;
+  Local_R2.N.C3 = Local_R1.N.C3;
+  Local_R2.N.B  = Local_R1.N.B;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/p4.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/p4.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/p4.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,64 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init4.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : db 0f 49 40\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 40 49 0f db\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db\n" } */
+
+  Local_R1.F = Pi;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40\n" } */
+
+  Local_R2.F = Pi;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db\n" } */
+
+  Local_R1.F = Local_R2.F;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40\n" } */
+
+  Local_R2.F = Local_R1.F;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/t1.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/t1.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/t1.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init1.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.I = My_R1.I + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12\n" } */
+
+  Local_R2.I = My_R2.I + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79\n" } */
+
+  Local_R1.I = 0x12345678;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12\n" } */
+
+  Local_R2.I = 0x12345678;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78\n" } */
+
+  Local_R1.I = Local_R1.I + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12\n" } */
+
+  Local_R2.I = Local_R2.I + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/p5.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/p5.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/p5.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.A[0] = 0xAB0012;
+  Local_R1.A[1] = 0xCD0034;
+  Local_R1.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.A[0] = 0xAB0012;
+  Local_R2.A[1] = 0xCD0034;
+  Local_R2.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = Local_R2.I;
+  Local_R1.A[0] = Local_R2.A[0];
+  Local_R1.A[1] = Local_R2.A[1];
+  Local_R1.A[2] = Local_R2.A[2];
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = Local_R1.I;
+  Local_R2.A[0] = Local_R1.A[0];
+  Local_R2.A[1] = Local_R1.A[1];
+  Local_R2.A[2] = Local_R1.A[2];
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/r3.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/r3.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/r3.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init3.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int Get_Elem1 (struct R1 R)
+{
+  struct R1 Tmp = R;
+  return Tmp.I;
+}
+
+void Set_Elem1 (struct R1 *R, int I)
+{
+  struct R1 Tmp = *R;
+  Tmp.I = I;
+  *R = Tmp;
+}
+
+int Get_Elem2 (struct R2 R)
+{
+  struct R2 Tmp = R;
+  return Tmp.I;
+}
+
+void Set_Elem2 (struct R2 *R, int I)
+{
+  struct R2 Tmp = *R;
+  Tmp.I = I;
+  *R = Tmp;
+}
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  if (Get_Elem1 (A1) != 0x78ABCDEF) abort ();
+
+  Set_Elem1 (&A1, 0xCD0034);
+  if (Get_Elem1 (A1) != 0xCD0034) abort ();
+
+  if (Get_Elem2 (A2) != 0x78ABCDEF) abort ();
+
+  Set_Elem2 (&A2, 0xCD0034);
+  if (Get_Elem2 (A2) != 0xCD0034) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/t2.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/t2.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/t2.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,92 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init2.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.S1 = My_R1.S1 - 1;
+  Local_R1.I  = My_R1.I + 1;
+  Local_R1.S2 = My_R1.S2 - 1;
+  Local_R1.A1 = My_R1.A1 % 16;
+  Local_R1.A2 = My_R1.A2 % 16;
+  Local_R1.A3 = My_R1.A3 % 16;
+  Local_R1.B  = !My_R1.B;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" } */
+
+  Local_R2.S1 = My_R2.S1 - 1;
+  Local_R2.I  = My_R2.I + 1;
+  Local_R2.S2 = My_R2.S2 - 1;
+  Local_R2.A1 = My_R2.A1 % 16;
+  Local_R2.A2 = My_R2.A2 % 16;
+  Local_R2.A3 = My_R2.A3 % 16;
+  Local_R2.B  = !My_R2.B;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" } */
+
+  Local_R1.S1 = 2;
+  Local_R1.I  = 0x12345678;
+  Local_R1.S2 = 1;
+  Local_R1.A1 = 0xAB;
+  Local_R1.A2 = 0xCD;
+  Local_R1.A3 = 0xEF;
+  Local_R1.B  = 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb\n" } */
+
+  Local_R2.S1 = 2;
+  Local_R2.I  = 0x12345678;
+  Local_R2.S2 = 1;
+  Local_R2.A1 = 0xAB;
+  Local_R2.A2 = 0xCD;
+  Local_R2.A3 = 0xEF;
+  Local_R2.B  = 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 84 8d 15 9e 15 5b 35 df\n" } */
+
+  Local_R1.S1 = Local_R1.S1 - 1;
+  Local_R1.I  = Local_R1.I + 1;
+  Local_R1.S2 = Local_R1.S2 - 1;
+  Local_R1.A1 = Local_R1.A1 % 16;
+  Local_R1.A2 = Local_R1.A2 % 16;
+  Local_R1.A3 = Local_R1.A3 % 16;
+  Local_R1.B  = !Local_R1.B;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03\n" } */
+
+  Local_R2.S1 = Local_R2.S1 - 1;
+  Local_R2.I  = Local_R2.I + 1;
+  Local_R2.S2 = Local_R2.S2 - 1;
+  Local_R2.A1 = Local_R2.A1 % 16;
+  Local_R2.A2 = Local_R2.A2 % 16;
+  Local_R2.A3 = Local_R2.A3 % 16;
+  Local_R2.B  = !Local_R2.B;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 44 8d 15 9e 40 58 34 1e\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/p6.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/p6.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/p6.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I      = 0x12345678;
+  Local_R1.N.A[0] = 0xAB0012;
+  Local_R1.N.A[1] = 0xCD0034;
+  Local_R1.N.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I      = 0x12345678;
+  Local_R2.N.A[0] = 0xAB0012;
+  Local_R2.N.A[1] = 0xCD0034;
+  Local_R2.N.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I      = Local_R2.I;
+  Local_R1.N.A[0] = Local_R2.N.A[0];
+  Local_R1.N.A[1] = Local_R2.N.A[1];
+  Local_R1.N.A[2] = Local_R2.N.A[2];
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I      = Local_R1.I;
+  Local_R2.N.A[0] = Local_R1.N.A[0];
+  Local_R2.N.A[1] = Local_R1.N.A[1];
+  Local_R2.N.A[2] = Local_R1.N.A[2];
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/p7.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/p7.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/p7.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init7.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.N.C1 = 0xAB0012;
+  Local_R1.N.C2 = 0xCD0034;
+  Local_R1.N.C3 = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.N.C1 = 0xAB0012;
+  Local_R2.N.C2 = 0xCD0034;
+  Local_R2.N.C3 = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = Local_R2.I;
+  Local_R1.N.C1 = Local_R2.N.C1;
+  Local_R1.N.C2 = Local_R2.N.C2;
+  Local_R1.N.C3 = Local_R2.N.C3;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = Local_R1.I;
+  Local_R2.N.C1 = Local_R1.N.C1;
+  Local_R2.N.C2 = Local_R1.N.C2;
+  Local_R2.N.C3 = Local_R1.N.C3;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/r5.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/r5.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/r5.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int Get_Elem1 (struct R1 R)
+{
+  struct R1 Tmp = R;
+  return Tmp.A[0];
+}
+
+void Set_Elem1 (struct R1 *R, int I)
+{
+  struct R1 Tmp = *R;
+  Tmp.A[0] = I;
+  *R = Tmp;
+}
+
+int Get_Elem2 (struct R2 R)
+{
+  struct R2 Tmp = R;
+  return Tmp.A[0];
+}
+
+void Set_Elem2 (struct R2 *R, int I)
+{
+  struct R2 Tmp = *R;
+  Tmp.A[0] = I;
+  *R = Tmp;
+}
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  if (Get_Elem1 (A1) != 0xAB0012) abort ();
+
+  Set_Elem1 (&A1, 0xCD0034);
+  if (Get_Elem1 (A1) != 0xCD0034) abort ();
+
+  if (Get_Elem2 (A2) != 0xAB0012) abort ();
+
+  Set_Elem2 (&A2, 0xCD0034);
+  if (Get_Elem2 (A2) != 0xCD0034) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/t3.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/t3.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/t3.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,92 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init3.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.S1   = My_R1.S1 - 1;
+  Local_R1.I    = My_R1.I + 1;
+  Local_R1.S2   = My_R1.S2 - 1;
+  Local_R1.N.C1 = My_R1.N.C1 % 16;
+  Local_R1.N.C2 = My_R1.N.C2 % 16;
+  Local_R1.N.C3 = My_R1.N.C3 % 16;
+  Local_R1.N.B  = My_R1.N.B % 2;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 01 7c f3 2a 1e 02 82 01\n" } */
+
+  Local_R2.S1   = My_R2.S1 - 1;
+  Local_R2.I    = My_R2.I + 1;
+  Local_R2.S2   = My_R2.S2 - 1;
+  Local_R2.N.C1 = My_R2.N.C1 % 16;
+  Local_R2.N.C2 = My_R2.N.C2 % 16;
+  Local_R2.N.C3 = My_R2.N.C3 % 16;
+  Local_R2.N.B  = My_R2.N.B % 2;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 05 e2 af 37 c0 04 10 30\n" } */
+
+  Local_R1.S1   = 2;
+  Local_R1.I    = 0x78ABCDEF;
+  Local_R1.S2   = 1;
+  Local_R1.N.C1 = 0x12;
+  Local_R1.N.C2 = 0x34;
+  Local_R1.N.C3 = 0x56;
+  Local_R1.N.B  = 4;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : c2 7b f3 2a 5e 12 9a 95\n" } */
+
+  Local_R2.S1   = 2;
+  Local_R2.I    = 0x78ABCDEF;
+  Local_R2.S2   = 1;
+  Local_R2.N.C1 = 0x12;
+  Local_R2.N.C2 = 0x34;
+  Local_R2.N.C3 = 0x56;
+  Local_R2.N.B  = 4;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 09 e2 af 37 bd 24 d2 b4\n" } */
+
+  Local_R1.S1   = Local_R1.S1 - 1;
+  Local_R1.I    = Local_R1.I + 1;
+  Local_R1.S2   = Local_R1.S2 - 1;
+  Local_R1.N.C1 = Local_R1.N.C1 % 16;
+  Local_R1.N.C2 = Local_R1.N.C2 % 16;
+  Local_R1.N.C3 = Local_R1.N.C3 % 16;
+  Local_R1.N.B  = Local_R1.N.B % 2;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 01 7c f3 2a 1e 02 82 01\n" } */
+
+  Local_R2.S1   = Local_R2.S1 - 1;
+  Local_R2.I    = Local_R2.I + 1;
+  Local_R2.S2   = Local_R2.S2 - 1;
+  Local_R2.N.C1 = Local_R2.N.C1 % 16;
+  Local_R2.N.C2 = Local_R2.N.C2 % 16;
+  Local_R2.N.C3 = Local_R2.N.C3 % 16;
+  Local_R2.N.B  = Local_R2.N.B % 2;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 05 e2 af 37 c0 04 10 30\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/r6.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/r6.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/r6.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int Get_Elem1 (struct R1 R)
+{
+  struct R1 Tmp = R;
+  return Tmp.N.A[0];
+}
+
+void Set_Elem1 (struct R1 *R, int I)
+{
+  struct R1 Tmp = *R;
+  Tmp.N.A[0] = I;
+  *R = Tmp;
+}
+
+int Get_Elem2 (struct R2 R)
+{
+  struct R2 Tmp = R;
+  return Tmp.N.A[0];
+}
+
+void Set_Elem2 (struct R2 *R, int I)
+{
+  struct R2 Tmp = *R;
+  Tmp.N.A[0] = I;
+  *R = Tmp;
+}
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  if (Get_Elem1 (A1) != 0xAB0012) abort ();
+
+  Set_Elem1 (&A1, 0xCD0034);
+  if (Get_Elem1 (A1) != 0xCD0034) abort ();
+
+  if (Get_Elem2 (A2) != 0xAB0012) abort ();
+
+  Set_Elem2 (&A2, 0xCD0034);
+  if (Get_Elem2 (A2) != 0xCD0034) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/p8.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/p8.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/p8.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init8.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.N.C1 = 0xAB0012;
+  Local_R1.N.C2 = 0xCD0034;
+  Local_R1.N.C3 = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.N.C1 = 0xAB0012;
+  Local_R2.N.C2 = 0xCD0034;
+  Local_R2.N.C3 = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I    = Local_R2.I;
+  Local_R1.N.C1 = Local_R2.N.C1;
+  Local_R1.N.C2 = Local_R2.N.C2;
+  Local_R1.N.C3 = Local_R2.N.C3;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I    = Local_R1.I;
+  Local_R2.N.C1 = Local_R1.N.C1;
+  Local_R2.N.C2 = Local_R1.N.C2;
+  Local_R2.N.C3 = Local_R1.N.C3;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/t4.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/t4.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/t4.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init4.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.F = My_R1.F + 1.0f;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : ee 87 84 40\n" } */
+
+  Local_R2.F = My_R2.F + 1.0f;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 84 87 ee\n" } */
+
+  Local_R1.F = Pi;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : db 0f 49 40\n" } */
+
+  Local_R2.F = Pi;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 49 0f db\n" } */
+
+  Local_R1.F = Local_R1.F + 1.0f;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : ee 87 84 40\n" } */
+
+  Local_R2.F = Local_R2.F + 1.0f;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 84 87 ee\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/r7.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/r7.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/r7.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init7.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int Get_Elem1 (struct R1 R)
+{
+  struct R1 Tmp = R;
+  return Tmp.N.C1;
+}
+
+void Set_Elem1 (struct R1 *R, int I)
+{
+  struct R1 Tmp = *R;
+  Tmp.N.C1 = I;
+  *R = Tmp;
+}
+
+int Get_Elem2 (struct R2 R)
+{
+  struct R2 Tmp = R;
+  return Tmp.N.C1;
+}
+
+void Set_Elem2 (struct R2 *R, int I)
+{
+  struct R2 Tmp = *R;
+  Tmp.N.C1 = I;
+  *R = Tmp;
+}
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  if (Get_Elem1 (A1) != 0xAB0012) abort ();
+
+  Set_Elem1 (&A1, 0xCD0034);
+  if (Get_Elem1 (A1) != 0xCD0034) abort ();
+
+  if (Get_Elem2 (A2) != 0xAB0012) abort ();
+
+  Set_Elem2 (&A2, 0xCD0034);
+  if (Get_Elem2 (A2) != 0xCD0034) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/p9.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/p9.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/p9.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,64 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init9.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  put ("My_R1    :");
+  dump (&My_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "My_R1    : 18 2d 44 54 fb 21 09 40\n" } */
+
+  put ("My_R2    :");
+  dump (&My_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "My_R2    : 40 09 21 fb 54 44 2d 18\n" } */
+
+  Local_R1 = My_R1;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  Local_R2 = My_R2;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  Local_R1.F = Pi;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  Local_R2.F = Pi;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  Local_R1.F = Local_R2.F;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  Local_R2.F = Local_R1.F;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/t5.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/t5.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/t5.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init5.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.I    = My_R1.I + 1;
+  Local_R1.A[0] = My_R1.A[0] + 1;
+  Local_R1.A[1] = My_R1.A[1] + 1;
+  Local_R1.A[2] = My_R1.A[2] + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R2.I    = My_R2.I + 1;
+  Local_R2.A[0] = My_R2.A[0] + 1;
+  Local_R2.A[1] = My_R2.A[1] + 1;
+  Local_R2.A[2] = My_R2.A[2] + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.A[0] = 0xAB0012;
+  Local_R1.A[1] = 0xCD0034;
+  Local_R1.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.A[0] = 0xAB0012;
+  Local_R2.A[1] = 0xCD0034;
+  Local_R2.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = Local_R1.I + 1;
+  Local_R1.A[0] = Local_R1.A[0] + 1;
+  Local_R1.A[1] = Local_R1.A[1] + 1;
+  Local_R1.A[2] = Local_R1.A[2] + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R2.I    = Local_R2.I + 1;
+  Local_R2.A[0] = Local_R2.A[0] + 1;
+  Local_R2.A[1] = Local_R2.A[1] + 1;
+  Local_R2.A[2] = Local_R2.A[2] + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/init1.h
===================================================================
--- gcc/testsuite/c-c++-common/sso/init1.h	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/init1.h	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,12 @@
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  int I;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  int I;
+};
+
+struct R1 My_R1 = { 0x12345678 };
+struct R2 My_R2 = { 0x12345678 };
Index: gcc/testsuite/c-c++-common/sso/r8.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/r8.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/r8.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init8.h"
+#include "dump.h"
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int Get_Elem1 (struct R1 R)
+{
+  struct R1 Tmp = R;
+  return Tmp.N.C1;
+}
+
+void Set_Elem1 (struct R1 *R, int I)
+{
+  struct R1 Tmp = *R;
+  Tmp.N.C1 = I;
+  *R = Tmp;
+}
+
+int Get_Elem2 (struct R2 R)
+{
+  struct R2 Tmp = R;
+  return Tmp.N.C1;
+}
+
+void Set_Elem2 (struct R2 *R, int I)
+{
+  struct R2 Tmp = *R;
+  Tmp.N.C1 = I;
+  *R = Tmp;
+}
+
+int main (void)
+{
+  struct R1 A1 = My_R1;
+  struct R2 A2 = My_R2;
+
+  put ("A1 :");
+  dump (&A1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "A1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  put ("A2 :");
+  dump (&A2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "A2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  if (Get_Elem1 (A1) != 0xAB0012) abort ();
+
+  Set_Elem1 (&A1, 0xCD0034);
+  if (Get_Elem1 (A1) != 0xCD0034) abort ();
+
+  if (Get_Elem2 (A2) != 0xAB0012) abort ();
+
+  Set_Elem2 (&A2, 0xCD0034);
+  if (Get_Elem2 (A2) != 0xCD0034) abort ();
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/t6.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/t6.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/t6.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init6.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.I      = My_R1.I + 1;
+  Local_R1.N.A[0] = My_R1.N.A[0] + 1;
+  Local_R1.N.A[1] = My_R1.N.A[1] + 1;
+  Local_R1.N.A[2] = My_R1.N.A[2] + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R2.I      = My_R2.I + 1;
+  Local_R2.N.A[0] = My_R2.N.A[0] + 1;
+  Local_R2.N.A[1] = My_R2.N.A[1] + 1;
+  Local_R2.N.A[2] = My_R2.N.A[2] + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R1.I      = 0x12345678;
+  Local_R1.N.A[0] = 0xAB0012;
+  Local_R1.N.A[1] = 0xCD0034;
+  Local_R1.N.A[2] = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I      = 0x12345678;
+  Local_R2.N.A[0] = 0xAB0012;
+  Local_R2.N.A[1] = 0xCD0034;
+  Local_R2.N.A[2] = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I      = Local_R1.I + 1;
+  Local_R1.N.A[0] = Local_R1.N.A[0] + 1;
+  Local_R1.N.A[1] = Local_R1.N.A[1] + 1;
+  Local_R1.N.A[2] = Local_R1.N.A[2] + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R2.I      = Local_R2.I + 1;
+  Local_R2.N.A[0] = Local_R2.N.A[0] + 1;
+  Local_R2.N.A[1] = Local_R2.N.A[1] + 1;
+  Local_R2.N.A[2] = Local_R2.N.A[2] + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/init2.h
===================================================================
--- gcc/testsuite/c-c++-common/sso/init2.h	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/init2.h	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,24 @@
+struct __attribute__((scalar_storage_order("little-endian"), packed)) R1
+{
+  unsigned S1 : 2;
+  unsigned I  : 32;
+  unsigned S2 : 2;
+  unsigned A1 : 9;
+  unsigned A2 : 9;
+  unsigned A3 : 9;
+  unsigned B  : 1;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"), packed)) R2
+{
+  unsigned S1 : 2;
+  unsigned I  : 32;
+  unsigned S2 : 2;
+  unsigned A1 : 9;
+  unsigned A2 : 9;
+  unsigned A3 : 9;
+  unsigned B  : 1;
+};
+
+struct R1 My_R1 = { 2, 0x12345678, 1, 0xAB, 0xCD, 0xEF, 1 };
+struct R2 My_R2 = { 2, 0x12345678, 1, 0xAB, 0xCD, 0xEF, 1 };
Index: gcc/testsuite/c-c++-common/sso/t7.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/t7.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/t7.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init7.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.I    = My_R1.I + 1;
+  Local_R1.N.C1 = My_R1.N.C1 + 1;
+  Local_R1.N.C2 = My_R1.N.C2 + 1;
+  Local_R1.N.C3 = My_R1.N.C3 + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R2.I    = My_R2.I + 1;
+  Local_R2.N.C1 = My_R2.N.C1 + 1;
+  Local_R2.N.C2 = My_R2.N.C2 + 1;
+  Local_R2.N.C3 = My_R2.N.C3 + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.N.C1 = 0xAB0012;
+  Local_R1.N.C2 = 0xCD0034;
+  Local_R1.N.C3 = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.N.C1 = 0xAB0012;
+  Local_R2.N.C2 = 0xCD0034;
+  Local_R2.N.C3 = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R1.I    = Local_R1.I + 1;
+  Local_R1.N.C1 = Local_R1.N.C1 + 1;
+  Local_R1.N.C2 = Local_R1.N.C2 + 1;
+  Local_R1.N.C3 = Local_R1.N.C3 + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R2.I    = Local_R2.I + 1;
+  Local_R2.N.C1 = Local_R2.N.C1 + 1;
+  Local_R2.N.C2 = Local_R2.N.C2 + 1;
+  Local_R2.N.C3 = Local_R2.N.C3 + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/init3.h
===================================================================
--- gcc/testsuite/c-c++-common/sso/init3.h	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/init3.h	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,34 @@
+struct __attribute__((scalar_storage_order("little-endian"), packed)) Nested1
+{
+  unsigned C1 : 7;
+  unsigned C2 : 7;
+  unsigned C3 : 7;
+  unsigned B  : 3;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"), packed)) R1
+{
+  unsigned S1 : 6;
+  unsigned I  : 32;
+  unsigned S2 : 2;
+  struct Nested1 N;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"), packed)) Nested2
+{
+  unsigned C1 : 7;
+  unsigned C2 : 7;
+  unsigned C3 : 7;
+  unsigned B  : 3;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"), packed)) R2
+{
+  unsigned S1 : 6;
+  unsigned I  : 32;
+  unsigned S2 : 2;
+  struct Nested2 N;
+};
+
+struct R1 My_R1 = { 2, 0x78ABCDEF, 1, { 0x12, 0x34, 0x56, 4 } };
+struct R2 My_R2 = { 2, 0x78ABCDEF, 1, { 0x12, 0x34, 0x56, 4 } };
Index: gcc/testsuite/c-c++-common/sso/t8.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/t8.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/t8.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init8.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.I    = My_R1.I + 1;
+  Local_R1.N.C1 = My_R1.N.C1 + 1;
+  Local_R1.N.C2 = My_R1.N.C2 + 1;
+  Local_R1.N.C3 = My_R1.N.C3 + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R2.I    = My_R2.I + 1;
+  Local_R2.N.C1 = My_R2.N.C1 + 1;
+  Local_R2.N.C2 = My_R2.N.C2 + 1;
+  Local_R2.N.C3 = My_R2.N.C3 + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  Local_R1.I    = 0x12345678;
+  Local_R1.N.C1 = 0xAB0012;
+  Local_R1.N.C2 = 0xCD0034;
+  Local_R1.N.C3 = 0xEF0056;
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 78 56 34 12 00 ab 00 12 00 cd 00 34 00 ef 00 56\n" } */
+
+  Local_R2.I    = 0x12345678;
+  Local_R2.N.C1 = 0xAB0012;
+  Local_R2.N.C2 = 0xCD0034;
+  Local_R2.N.C3 = 0xEF0056;
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 78 12 00 ab 00 34 00 cd 00 56 00 ef 00\n" } */
+
+  Local_R1.I    = Local_R1.I + 1;
+  Local_R1.N.C1 = Local_R1.N.C1 + 1;
+  Local_R1.N.C2 = Local_R1.N.C2 + 1;
+  Local_R1.N.C3 = Local_R1.N.C3 + 1;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 79 56 34 12 00 ab 00 13 00 cd 00 35 00 ef 00 57\n" } */
+
+  Local_R2.I    = Local_R2.I + 1;
+  Local_R2.N.C1 = Local_R2.N.C1 + 1;
+  Local_R2.N.C2 = Local_R2.N.C2 + 1;
+  Local_R2.N.C3 = Local_R2.N.C3 + 1;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 12 34 56 79 13 00 ab 00 35 00 cd 00 57 00 ef 00\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/init4.h
===================================================================
--- gcc/testsuite/c-c++-common/sso/init4.h	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/init4.h	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,14 @@
+#define Pi 3.1415927f
+
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  float F;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  float F;
+};
+
+struct R1 My_R1 = { Pi };
+struct R2 My_R2 = { Pi };
Index: gcc/testsuite/c-c++-common/sso/t9.c
===================================================================
--- gcc/testsuite/c-c++-common/sso/t9.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/t9.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+#include "init9.h"
+#include "dump.h"
+
+int main (void)
+{
+  struct R1 Local_R1;
+  struct R2 Local_R2;
+
+  Local_R1.F = My_R1.F + 1.0;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 8c 16 22 aa fd 90 10 40\n" } */
+
+  Local_R2.F = My_R2.F + 1.0;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 10 90 fd aa 22 16 8c\n" } */
+
+  Local_R1.F = Pi;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 18 2d 44 54 fb 21 09 40\n" } */
+
+  Local_R2.F = Pi;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 09 21 fb 54 44 2d 18\n" } */
+
+  Local_R1.F = Local_R1.F + 1.0;
+
+  put ("Local_R1 :");
+  dump (&Local_R1, sizeof (struct R1));
+  new_line ();
+  /* { dg-output "Local_R1 : 8c 16 22 aa fd 90 10 40\n" } */
+
+  Local_R2.F = Local_R2.F + 1.0;
+
+  put ("Local_R2 :");
+  dump (&Local_R2, sizeof (struct R2));
+  new_line ();
+  /* { dg-output "Local_R2 : 40 10 90 fd aa 22 16 8c\n" } */
+
+  return 0;
+}
Index: gcc/testsuite/c-c++-common/sso/init5.h
===================================================================
--- gcc/testsuite/c-c++-common/sso/init5.h	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso/init5.h	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,14 @@
+struct __attribute__((scalar_storage_order("little-endian"))) R1
+{
+  int I;
+  int A[3];
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) R2
+{
+  int I;
+  int A[3];
+};
+
+struct R1 My_R1 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
+struct R2 My_R2 = { 0x12345678, { 0xAB0012, 0xCD0034, 0xEF0056 } };
Index: gcc/testsuite/c-c++-common/sso-1.c
===================================================================
--- gcc/testsuite/c-c++-common/sso-1.c	(.../trunk)	(revision 0)
+++ gcc/testsuite/c-c++-common/sso-1.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -0,0 +1,94 @@
+/* Test support of scalar_storage_order attribute */
+
+/* { dg-do compile } */
+
+struct __attribute__((scalar_storage_order("big-endian"))) S1
+{
+  int i;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) S2
+{
+  int i;
+};
+
+struct __attribute__((scalar_storage_order("other"))) S3 {}; /* { dg-error "must be one of .big-endian. or .little-endian." } */
+
+void incompatible_assign (struct S1 *s1, struct S2 *s2)
+{
+  *s1 = *s2; /* { dg-error "(incompatible types|no match)" } */
+}
+
+int *addr1 (int which, struct S1 *s1, struct S2 *s2)
+{
+  return (which == 1 ? &s1->i : &s2->i); /* { dg-error "address of scalar with reverse storage order" } */
+}
+
+struct __attribute__((scalar_storage_order("big-endian"))) S4
+{
+  int a[4];
+  struct S2 s2;
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) S5
+{
+  int a[4];
+  struct S1 s1;
+};
+
+void *addr2 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)s4->a : (void *)s5->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr3 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)&s4->a : (void *)&s5->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr4 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)&s4->a[0] : (void *)&s5->a[0]); /* { dg-error "address of scalar with reverse storage order" } */
+}
+
+void *addr5 (int which, struct S4 *s4, struct S5 *s5)
+{
+  return (which == 1 ? (void *)&s4->s2 : (void *) &s5->s1); /* ok */
+}
+
+struct __attribute__((scalar_storage_order("big-endian"))) S6
+{
+  int a[4][2];
+  struct S2 s2[2];
+};
+
+struct __attribute__((scalar_storage_order("little-endian"))) S7
+{
+  int a[4][2];
+  struct S1 s1[2];
+};
+
+void *addr6 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)s6->a : (void *)s7->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr7 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->a : (void *)&s7->a); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr8 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->a[0] : (void *)&s7->a[0]); /* { dg-warning "address of array with reverse scalar storage order" } */
+}
+
+void *addr9 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->a[0][0] : (void *)&s7->a[0][0]); /* { dg-error "address of scalar with reverse storage order" } */
+}
+
+void *addr10 (int which, struct S6 *s6, struct S7 *s7)
+{
+  return (which == 1 ? (void *)&s6->s2 : (void *)&s7->s1); /* ok */
+}

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2015-11-08 18:30 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-06 10:57 [patch 0/6] scalar-storage-order merge (2) Eric Botcazou
2015-10-06 11:01 ` [patch 1/6] scalar-storage-order merge: Ada front-end Eric Botcazou
2015-10-12 22:23   ` Jeff Law
2015-10-06 11:02 ` [patch 2/6] scalar-storage-order merge: C front-end Eric Botcazou
2015-10-13 11:32   ` Jeff Law
2015-10-19  8:50     ` Eric Botcazou
2015-10-28 16:48   ` Joseph Myers
2015-10-28 17:32     ` Jeff Law
2015-10-28 22:34     ` Eric Botcazou
2015-10-28 23:36       ` Mike Stump
2015-10-29  0:23         ` Joseph Myers
2015-10-30  8:59         ` Eric Botcazou
2015-10-30 14:50           ` Mike Stump
2015-10-06 11:03 ` [patch 3/6] scalar-storage-order merge: C++ front-end Eric Botcazou
2015-10-12 22:27   ` Jeff Law
2015-10-06 11:05 ` [patch 4/6] scalar-storage-order merge: bulk Eric Botcazou
2015-10-13 16:07   ` Jeff Law
2015-10-20 16:35     ` Eric Botcazou
2015-10-06 11:06 ` [patch 5/6] scalar-storage-order merge: rest Eric Botcazou
2015-10-06 11:09   ` Eric Botcazou
2015-10-13 16:44   ` Jeff Law
2015-10-06 11:08 ` [patch 6/6] scalar-storage-order merge: testsuite Eric Botcazou
2015-10-12 22:26   ` Jeff Law
2015-10-09 11:33 ` [patch 0/6] scalar-storage-order merge (2) Bernd Schmidt
2015-10-13 17:33   ` Eric Botcazou
2015-10-14 15:25     ` Trevor Saunders
2015-10-14 15:33       ` Jeff Law
2015-11-08 18:30 ` Eric Botcazou
  -- strict thread matches above, loose matches on Subject: below --
2015-06-16  8:46 [patch 0/6] scalar-storage-order merge Eric Botcazou
2015-06-16  9:59 ` [patch 6/6] scalar-storage-order merge: testsuite Eric Botcazou
2015-06-16 13:30   ` Richard Earnshaw
2015-06-18 20:29     ` Eric Botcazou
2015-06-19  9:17       ` Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).