summaryrefslogtreecommitdiff
path: root/gcc/ada/exp_pakd.adb
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2012-07-12 12:56:02 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2012-07-12 12:56:02 +0200
commit759658521a6e6c4f1b426752ea568ad69806b8a2 (patch)
tree3f4ee2a3f34ece8b71fc886093da3456a5ae2ad1 /gcc/ada/exp_pakd.adb
parent727e7b1a870bdc057c4cb6d7d09ef1b56a84f222 (diff)
downloadgcc-759658521a6e6c4f1b426752ea568ad69806b8a2.tar.gz
[multiple changes]
2012-07-12 Vasiliy Fofanov <fofanov@adacore.com> * vms_data.ads: Add VMS qualifiers for -gnatn1/2 switches. 2012-07-12 Thomas Quinot <quinot@adacore.com> * exp_ch5.adb, exp_pakd.adb, rtsfind.ads, freeze.adb, sem_util.adb, sem_util.ads, exp_aggr.adb (Exp_Aggr.Packed_Array_Aggregate_Handled): Simplify processing for reverse storage order aggregate. (Exp_Pakd.Byte_Swap): New utility routine used by... (Exp_Pakd.Expand_Bit_Packed_Element_Set, Expand_Packed_Element_Reference): For the case of a free-standing packed array with reverse storage order, perform byte swapping. (Rtsfind): Make new entities RE_Bswap_{16,32,64} available. (Freeze.Check_Component_Storage_Order): New utility routine to enforce legality rules for nested composite types whose enclosing composite has an explicitly defined Scalar_Storage_Order attribute. (Sem_Util.In_Reverse_Storage_Order_Object): Renamed from Sem_Util.In_Reverse_Storage_Order_Record, as SSO now applies to array types as well. (Exp_Ch5.Expand_Assign_Array): Remove now unnecessary kludge for change of scalar storage order in assignments. The Lhs and Rhs now always have the same scalar storage order. 2012-07-12 Hristian Kirtchev <kirtchev@adacore.com> * g-debpoo.adb (Allocate): Add local constant No_Element. Initialize the allocated memory chunk to No_Element. 2012-07-12 Ed Schonberg <schonberg@adacore.com> * sem_ch12.adb (Validate_Derived_Type_Instance): Handle properly the case of an instance of a child unit where a formal derived type DT is an extension of a type T declared in a parent unit, and the actual in the instance of the child is the type T declared in the parent instance, and that actual is not a derived type. 2012-07-12 Eric Botcazou <ebotcazou@adacore.com> Tristan Gingold <gingold@adacore.com> * system-hpux-ia64.ads: Enable ZCX by default. * gcc-interface/Makefile.in: Use alternate stack on ia64-hpux. Change soext to .so. From-SVN: r189439
Diffstat (limited to 'gcc/ada/exp_pakd.adb')
-rw-r--r--gcc/ada/exp_pakd.adb73
1 files changed, 72 insertions, 1 deletions
diff --git a/gcc/ada/exp_pakd.adb b/gcc/ada/exp_pakd.adb
index ee75cf732be..b958383f933 100644
--- a/gcc/ada/exp_pakd.adb
+++ b/gcc/ada/exp_pakd.adb
@@ -543,6 +543,42 @@ package body Exp_Pakd is
-- array type on the fly). Such actions are inserted into the tree
-- directly using Insert_Action.
+ function Byte_Swap (N : Node_Id) return Node_Id;
+ -- Wrap N in a call to a byte swapping function, with appropriate type
+ -- conversions.
+
+ ---------------
+ -- Byte_Swap --
+ ---------------
+
+ function Byte_Swap (N : Node_Id) return Node_Id is
+ Loc : constant Source_Ptr := Sloc (N);
+ T : constant Entity_Id := Etype (N);
+ Swap_RE : RE_Id;
+ Swap_F : Entity_Id;
+
+ begin
+ pragma Assert (Esize (T) > 8);
+
+ if Esize (T) <= 16 then
+ Swap_RE := RE_Bswap_16;
+ elsif Esize (T) <= 32 then
+ Swap_RE := RE_Bswap_32;
+ else pragma Assert (Esize (T) <= 64);
+ Swap_RE := RE_Bswap_64;
+ end if;
+
+ Swap_F := RTE (Swap_RE);
+
+ return Unchecked_Convert_To
+ (T,
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (Swap_F, Loc),
+ Parameter_Associations =>
+ New_List (Unchecked_Convert_To (Etype (Swap_F), N))));
+ end Byte_Swap;
+
------------------------------
-- Compute_Linear_Subscript --
------------------------------
@@ -1304,6 +1340,12 @@ package body Exp_Pakd is
-- contains the value. Otherwise Rhs_Val_Known is set False, and
-- the Rhs_Val is undefined.
+ Require_Byte_Swapping : Boolean := False;
+ -- True if byte swapping required, for the Reverse_Storage_Order case
+ -- when the packed array is a free-standing object. (If it is part
+ -- of a composite type, and therefore potentially not aligned on a byte
+ -- boundary, the swapping is done by the back-end).
+
function Get_Shift return Node_Id;
-- Function used to get the value of Shift, making sure that it
-- gets duplicated if the function is called more than once.
@@ -1415,6 +1457,11 @@ package body Exp_Pakd is
-- Obj := atyp!((Obj and Mask1) or (shift_left (rhs, Shift)))
+ -- or in the case of a freestanding Reverse_Storage_Order object,
+
+ -- Obj := Swap (atyp!((Swap (Obj) and Mask1)
+ -- or (shift_left (rhs, Shift))))
+
-- where Mask1 is obtained by shifting Cmask left Shift bits
-- and then complementing the result.
@@ -1485,6 +1532,14 @@ package body Exp_Pakd is
Set_Etype (Obj, T);
Set_Etype (New_Lhs, T);
Set_Etype (New_Rhs, T);
+
+ if Reverse_Storage_Order (Base_Type (Atyp))
+ and then Esize (T) > 8
+ and then not In_Reverse_Storage_Order_Object (Obj)
+ then
+ Require_Byte_Swapping := True;
+ New_Rhs := Byte_Swap (New_Rhs);
+ end if;
end;
-- First we deal with the "and"
@@ -1615,6 +1670,11 @@ package body Exp_Pakd is
end;
end if;
+ if Require_Byte_Swapping then
+ Set_Etype (New_Rhs, Etype (Obj));
+ New_Rhs := Byte_Swap (New_Rhs);
+ end if;
+
-- Now do the rewrite
Rewrite (N,
@@ -1977,6 +2037,17 @@ package body Exp_Pakd is
Lit := Make_Integer_Literal (Loc, Cmask);
Set_Print_In_Hex (Lit);
+ -- Byte swapping required for the Reverse_Storage_Order case, but
+ -- only for a free-standing object (see note on Require_Byte_Swapping
+ -- in Expand_Bit_Packed_Element_Set).
+
+ if Reverse_Storage_Order (Atyp)
+ and then Esize (Atyp) > 8
+ and then not In_Reverse_Storage_Order_Object (Obj)
+ then
+ Obj := Byte_Swap (Obj);
+ end if;
+
-- We generate a shift right to position the field, followed by a
-- masking operation to extract the bit field, and we finally do an
-- unchecked conversion to convert the result to the required target.
@@ -2726,7 +2797,7 @@ package body Exp_Pakd is
-- We also have to adjust if the storage order is reversed
- if Bytes_Big_Endian xor In_Reverse_Storage_Order_Record (Obj) then
+ if Bytes_Big_Endian xor Reverse_Storage_Order (Base_Type (Atyp)) then
Shift :=
Make_Op_Subtract (Loc,
Left_Opnd => Make_Integer_Literal (Loc, Osiz - Csiz),