diff options
Diffstat (limited to 'gcc')
121 files changed, 53704 insertions, 7939 deletions
diff --git a/gcc/ada/libgnat/s-pack03.adb b/gcc/ada/libgnat/s-pack03.adb index 56b036e..9df8774 100644 --- a/gcc/ada/libgnat/s-pack03.adb +++ b/gcc/ada/libgnat/s-pack03.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_03 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 03 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_03 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_03; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_03; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_03; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_03; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_03; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_03; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_03; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_03; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_03 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_03 -- @@ -90,33 +373,47 @@ package body System.Pack_03 is N : Natural; Rev_SSO : Boolean) return Bits_03 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_03; @@ -130,32 +427,46 @@ package body System.Pack_03 is E : Bits_03; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_03; diff --git a/gcc/ada/libgnat/s-pack05.adb b/gcc/ada/libgnat/s-pack05.adb index 0abccaf9..39b819a 100644 --- a/gcc/ada/libgnat/s-pack05.adb +++ b/gcc/ada/libgnat/s-pack05.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_05 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 05 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_05 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_05; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_05; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_05; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_05; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_05; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_05; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_05; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_05; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_05 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_05 -- @@ -90,33 +373,47 @@ package body System.Pack_05 is N : Natural; Rev_SSO : Boolean) return Bits_05 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_05; @@ -130,32 +427,46 @@ package body System.Pack_05 is E : Bits_05; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_05; diff --git a/gcc/ada/libgnat/s-pack06.adb b/gcc/ada/libgnat/s-pack06.adb index 3b85634..3fe0b48 100644 --- a/gcc/ada/libgnat/s-pack06.adb +++ b/gcc/ada/libgnat/s-pack06.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_06 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 06 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_06 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_06; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_06 or SetU_06 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_06; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_06 or SetU_06 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_06; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_06 or SetU_06 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_06; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_06 or SetU_06 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_06; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_06 or SetU_06 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_06; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_06 or SetU_06 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_06; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_06 or SetU_06 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_06; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_06 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_06 or SetU_06 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_06 -- @@ -106,33 +501,47 @@ package body System.Pack_06 is N : Natural; Rev_SSO : Boolean) return Bits_06 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_06; @@ -145,33 +554,47 @@ package body System.Pack_06 is N : Natural; Rev_SSO : Boolean) return Bits_06 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_06; @@ -185,32 +608,46 @@ package body System.Pack_06 is E : Bits_06; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_06; @@ -225,32 +662,46 @@ package body System.Pack_06 is E : Bits_06; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_06; diff --git a/gcc/ada/libgnat/s-pack07.adb b/gcc/ada/libgnat/s-pack07.adb index e93aca5..1f2924c 100644 --- a/gcc/ada/libgnat/s-pack07.adb +++ b/gcc/ada/libgnat/s-pack07.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_07 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 07 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_07 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_07; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_07; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_07; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_07; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_07; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_07; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_07; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_07; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_07 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_07 -- @@ -90,33 +373,47 @@ package body System.Pack_07 is N : Natural; Rev_SSO : Boolean) return Bits_07 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_07; @@ -130,32 +427,46 @@ package body System.Pack_07 is E : Bits_07; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_07; diff --git a/gcc/ada/libgnat/s-pack09.adb b/gcc/ada/libgnat/s-pack09.adb index 85bc49a..7c8f785 100644 --- a/gcc/ada/libgnat/s-pack09.adb +++ b/gcc/ada/libgnat/s-pack09.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_09 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 09 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_09 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_09; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_09; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_09; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_09; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_09; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_09; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_09; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_09; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_09 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_09 -- @@ -90,33 +373,47 @@ package body System.Pack_09 is N : Natural; Rev_SSO : Boolean) return Bits_09 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_09; @@ -130,32 +427,46 @@ package body System.Pack_09 is E : Bits_09; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_09; diff --git a/gcc/ada/libgnat/s-pack10.adb b/gcc/ada/libgnat/s-pack10.adb index 6bf3ab7..fe97ef9 100644 --- a/gcc/ada/libgnat/s-pack10.adb +++ b/gcc/ada/libgnat/s-pack10.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_10 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 10 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_10 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_10; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_10 or SetU_10 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_10; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_10 or SetU_10 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_10; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_10 or SetU_10 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_10; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_10 or SetU_10 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_10; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_10 or SetU_10 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_10; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_10 or SetU_10 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_10; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_10 or SetU_10 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_10; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_10 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_10 or SetU_10 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_10 -- @@ -106,33 +501,47 @@ package body System.Pack_10 is N : Natural; Rev_SSO : Boolean) return Bits_10 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_10; @@ -145,33 +554,47 @@ package body System.Pack_10 is N : Natural; Rev_SSO : Boolean) return Bits_10 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_10; @@ -185,32 +608,46 @@ package body System.Pack_10 is E : Bits_10; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_10; @@ -225,32 +662,46 @@ package body System.Pack_10 is E : Bits_10; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_10; diff --git a/gcc/ada/libgnat/s-pack100.adb b/gcc/ada/libgnat/s-pack100.adb index b413f45..2688934 100644 --- a/gcc/ada/libgnat/s-pack100.adb +++ b/gcc/ada/libgnat/s-pack100.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_100 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 100 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_100 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_100; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_100 or SetU_100 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_100; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_100 or SetU_100 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_100; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_100 or SetU_100 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_100; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_100 or SetU_100 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_100; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_100 or SetU_100 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_100; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_100 or SetU_100 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_100; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_100 or SetU_100 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_100; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_100 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_100 or SetU_100 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_100 -- @@ -106,33 +501,47 @@ package body System.Pack_100 is N : Natural; Rev_SSO : Boolean) return Bits_100 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_100; @@ -145,33 +554,47 @@ package body System.Pack_100 is N : Natural; Rev_SSO : Boolean) return Bits_100 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_100; @@ -185,32 +608,46 @@ package body System.Pack_100 is E : Bits_100; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_100; @@ -225,32 +662,46 @@ package body System.Pack_100 is E : Bits_100; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_100; diff --git a/gcc/ada/libgnat/s-pack101.adb b/gcc/ada/libgnat/s-pack101.adb index 5d5fdb3..41a6c1b 100644 --- a/gcc/ada/libgnat/s-pack101.adb +++ b/gcc/ada/libgnat/s-pack101.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_101 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 101 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_101 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_101; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_101; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_101; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_101; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_101; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_101; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_101; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_101; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_101 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_101 -- @@ -90,33 +373,47 @@ package body System.Pack_101 is N : Natural; Rev_SSO : Boolean) return Bits_101 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_101; @@ -130,32 +427,46 @@ package body System.Pack_101 is E : Bits_101; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_101; diff --git a/gcc/ada/libgnat/s-pack102.adb b/gcc/ada/libgnat/s-pack102.adb index b00f67b..d8f7cad 100644 --- a/gcc/ada/libgnat/s-pack102.adb +++ b/gcc/ada/libgnat/s-pack102.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_102 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 102 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_102 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_102; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_102 or SetU_102 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_102; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_102 or SetU_102 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_102; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_102 or SetU_102 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_102; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_102 or SetU_102 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_102; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_102 or SetU_102 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_102; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_102 or SetU_102 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_102; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_102 or SetU_102 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_102; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_102 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_102 or SetU_102 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_102 -- @@ -106,33 +501,47 @@ package body System.Pack_102 is N : Natural; Rev_SSO : Boolean) return Bits_102 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_102; @@ -145,33 +554,47 @@ package body System.Pack_102 is N : Natural; Rev_SSO : Boolean) return Bits_102 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_102; @@ -185,32 +608,46 @@ package body System.Pack_102 is E : Bits_102; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_102; @@ -225,32 +662,46 @@ package body System.Pack_102 is E : Bits_102; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_102; diff --git a/gcc/ada/libgnat/s-pack103.adb b/gcc/ada/libgnat/s-pack103.adb index 0839c89..e2e108e 100644 --- a/gcc/ada/libgnat/s-pack103.adb +++ b/gcc/ada/libgnat/s-pack103.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_103 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 103 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_103 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_103; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_103; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_103; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_103; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_103; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_103; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_103; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_103; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_103 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_103 -- @@ -90,33 +373,47 @@ package body System.Pack_103 is N : Natural; Rev_SSO : Boolean) return Bits_103 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_103; @@ -130,32 +427,46 @@ package body System.Pack_103 is E : Bits_103; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_103; diff --git a/gcc/ada/libgnat/s-pack104.adb b/gcc/ada/libgnat/s-pack104.adb index b3430e5..42d1c12 100644 --- a/gcc/ada/libgnat/s-pack104.adb +++ b/gcc/ada/libgnat/s-pack104.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_104 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 104 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_104 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_104; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_104 or SetU_104 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_104; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_104 or SetU_104 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_104; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_104 or SetU_104 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_104; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_104 or SetU_104 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_104; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_104 or SetU_104 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_104; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_104 or SetU_104 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_104; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_104 or SetU_104 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_104; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_104 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_104 or SetU_104 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_104 -- @@ -106,33 +501,47 @@ package body System.Pack_104 is N : Natural; Rev_SSO : Boolean) return Bits_104 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_104; @@ -145,33 +554,47 @@ package body System.Pack_104 is N : Natural; Rev_SSO : Boolean) return Bits_104 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_104; @@ -185,32 +608,46 @@ package body System.Pack_104 is E : Bits_104; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_104; @@ -225,32 +662,46 @@ package body System.Pack_104 is E : Bits_104; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_104; diff --git a/gcc/ada/libgnat/s-pack105.adb b/gcc/ada/libgnat/s-pack105.adb index 4355aca..d97441f 100644 --- a/gcc/ada/libgnat/s-pack105.adb +++ b/gcc/ada/libgnat/s-pack105.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_105 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 105 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_105 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_105; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_105; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_105; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_105; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_105; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_105; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_105; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_105; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_105 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_105 -- @@ -90,33 +373,47 @@ package body System.Pack_105 is N : Natural; Rev_SSO : Boolean) return Bits_105 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_105; @@ -130,32 +427,46 @@ package body System.Pack_105 is E : Bits_105; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_105; diff --git a/gcc/ada/libgnat/s-pack106.adb b/gcc/ada/libgnat/s-pack106.adb index 870ab72..ccd8b10 100644 --- a/gcc/ada/libgnat/s-pack106.adb +++ b/gcc/ada/libgnat/s-pack106.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_106 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 106 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_106 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_106; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_106 or SetU_106 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_106; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_106 or SetU_106 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_106; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_106 or SetU_106 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_106; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_106 or SetU_106 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_106; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_106 or SetU_106 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_106; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_106 or SetU_106 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_106; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_106 or SetU_106 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_106; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_106 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_106 or SetU_106 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_106 -- @@ -106,33 +501,47 @@ package body System.Pack_106 is N : Natural; Rev_SSO : Boolean) return Bits_106 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_106; @@ -145,33 +554,47 @@ package body System.Pack_106 is N : Natural; Rev_SSO : Boolean) return Bits_106 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_106; @@ -185,32 +608,46 @@ package body System.Pack_106 is E : Bits_106; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_106; @@ -225,32 +662,46 @@ package body System.Pack_106 is E : Bits_106; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_106; diff --git a/gcc/ada/libgnat/s-pack107.adb b/gcc/ada/libgnat/s-pack107.adb index 2266717..9ac51de 100644 --- a/gcc/ada/libgnat/s-pack107.adb +++ b/gcc/ada/libgnat/s-pack107.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_107 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 107 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_107 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_107; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_107; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_107; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_107; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_107; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_107; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_107; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_107; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_107 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_107 -- @@ -90,33 +373,47 @@ package body System.Pack_107 is N : Natural; Rev_SSO : Boolean) return Bits_107 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_107; @@ -130,32 +427,46 @@ package body System.Pack_107 is E : Bits_107; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_107; diff --git a/gcc/ada/libgnat/s-pack108.adb b/gcc/ada/libgnat/s-pack108.adb index 87c8a33..3c71ff0 100644 --- a/gcc/ada/libgnat/s-pack108.adb +++ b/gcc/ada/libgnat/s-pack108.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_108 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 108 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_108 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_108; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_108 or SetU_108 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_108; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_108 or SetU_108 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_108; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_108 or SetU_108 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_108; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_108 or SetU_108 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_108; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_108 or SetU_108 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_108; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_108 or SetU_108 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_108; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_108 or SetU_108 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_108; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_108 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_108 or SetU_108 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_108 -- @@ -106,33 +501,47 @@ package body System.Pack_108 is N : Natural; Rev_SSO : Boolean) return Bits_108 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_108; @@ -145,33 +554,47 @@ package body System.Pack_108 is N : Natural; Rev_SSO : Boolean) return Bits_108 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_108; @@ -185,32 +608,46 @@ package body System.Pack_108 is E : Bits_108; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_108; @@ -225,32 +662,46 @@ package body System.Pack_108 is E : Bits_108; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_108; diff --git a/gcc/ada/libgnat/s-pack109.adb b/gcc/ada/libgnat/s-pack109.adb index 278d206..83a6965 100644 --- a/gcc/ada/libgnat/s-pack109.adb +++ b/gcc/ada/libgnat/s-pack109.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_109 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 109 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_109 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_109; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_109; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_109; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_109; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_109; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_109; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_109; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_109; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_109 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_109 -- @@ -90,33 +373,47 @@ package body System.Pack_109 is N : Natural; Rev_SSO : Boolean) return Bits_109 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_109; @@ -130,32 +427,46 @@ package body System.Pack_109 is E : Bits_109; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_109; diff --git a/gcc/ada/libgnat/s-pack11.adb b/gcc/ada/libgnat/s-pack11.adb index 61312ce..5f70095 100644 --- a/gcc/ada/libgnat/s-pack11.adb +++ b/gcc/ada/libgnat/s-pack11.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_11 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 11 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_11 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_11; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_11; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_11; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_11; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_11; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_11; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_11; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_11; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_11 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_11 -- @@ -90,33 +373,47 @@ package body System.Pack_11 is N : Natural; Rev_SSO : Boolean) return Bits_11 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_11; @@ -130,32 +427,46 @@ package body System.Pack_11 is E : Bits_11; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_11; diff --git a/gcc/ada/libgnat/s-pack110.adb b/gcc/ada/libgnat/s-pack110.adb index 40c5884..9f22788 100644 --- a/gcc/ada/libgnat/s-pack110.adb +++ b/gcc/ada/libgnat/s-pack110.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_110 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 110 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_110 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_110; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_110 or SetU_110 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_110; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_110 or SetU_110 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_110; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_110 or SetU_110 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_110; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_110 or SetU_110 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_110; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_110 or SetU_110 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_110; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_110 or SetU_110 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_110; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_110 or SetU_110 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_110; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_110 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_110 or SetU_110 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_110 -- @@ -106,33 +501,47 @@ package body System.Pack_110 is N : Natural; Rev_SSO : Boolean) return Bits_110 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_110; @@ -145,33 +554,47 @@ package body System.Pack_110 is N : Natural; Rev_SSO : Boolean) return Bits_110 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_110; @@ -185,32 +608,46 @@ package body System.Pack_110 is E : Bits_110; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_110; @@ -225,32 +662,46 @@ package body System.Pack_110 is E : Bits_110; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_110; diff --git a/gcc/ada/libgnat/s-pack111.adb b/gcc/ada/libgnat/s-pack111.adb index 4b4e5b4..71bd241 100644 --- a/gcc/ada/libgnat/s-pack111.adb +++ b/gcc/ada/libgnat/s-pack111.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_111 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 111 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_111 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_111; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_111; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_111; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_111; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_111; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_111; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_111; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_111; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_111 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_111 -- @@ -90,33 +373,47 @@ package body System.Pack_111 is N : Natural; Rev_SSO : Boolean) return Bits_111 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_111; @@ -130,32 +427,46 @@ package body System.Pack_111 is E : Bits_111; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_111; diff --git a/gcc/ada/libgnat/s-pack112.adb b/gcc/ada/libgnat/s-pack112.adb index 16dedbc..afa75c5 100644 --- a/gcc/ada/libgnat/s-pack112.adb +++ b/gcc/ada/libgnat/s-pack112.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_112 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 112 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_112 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_112; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_112 or SetU_112 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_112; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_112 or SetU_112 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_112; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_112 or SetU_112 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_112; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_112 or SetU_112 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_112; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_112 or SetU_112 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_112; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_112 or SetU_112 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_112; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_112 or SetU_112 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_112; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_112 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_112 or SetU_112 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_112 -- @@ -106,33 +501,47 @@ package body System.Pack_112 is N : Natural; Rev_SSO : Boolean) return Bits_112 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_112; @@ -145,33 +554,47 @@ package body System.Pack_112 is N : Natural; Rev_SSO : Boolean) return Bits_112 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_112; @@ -185,32 +608,46 @@ package body System.Pack_112 is E : Bits_112; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_112; @@ -225,32 +662,46 @@ package body System.Pack_112 is E : Bits_112; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_112; diff --git a/gcc/ada/libgnat/s-pack113.adb b/gcc/ada/libgnat/s-pack113.adb index 4376c2a..cbd2ec8 100644 --- a/gcc/ada/libgnat/s-pack113.adb +++ b/gcc/ada/libgnat/s-pack113.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_113 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 113 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_113 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_113; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_113; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_113; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_113; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_113; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_113; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_113; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_113; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_113 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_113 -- @@ -90,33 +373,47 @@ package body System.Pack_113 is N : Natural; Rev_SSO : Boolean) return Bits_113 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_113; @@ -130,32 +427,46 @@ package body System.Pack_113 is E : Bits_113; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_113; diff --git a/gcc/ada/libgnat/s-pack114.adb b/gcc/ada/libgnat/s-pack114.adb index 7d0d4c6..3a8f541 100644 --- a/gcc/ada/libgnat/s-pack114.adb +++ b/gcc/ada/libgnat/s-pack114.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_114 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 114 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_114 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_114; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_114 or SetU_114 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_114; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_114 or SetU_114 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_114; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_114 or SetU_114 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_114; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_114 or SetU_114 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_114; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_114 or SetU_114 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_114; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_114 or SetU_114 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_114; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_114 or SetU_114 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_114; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_114 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_114 or SetU_114 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_114 -- @@ -106,33 +501,47 @@ package body System.Pack_114 is N : Natural; Rev_SSO : Boolean) return Bits_114 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_114; @@ -145,33 +554,47 @@ package body System.Pack_114 is N : Natural; Rev_SSO : Boolean) return Bits_114 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_114; @@ -185,32 +608,46 @@ package body System.Pack_114 is E : Bits_114; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_114; @@ -225,32 +662,46 @@ package body System.Pack_114 is E : Bits_114; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_114; diff --git a/gcc/ada/libgnat/s-pack115.adb b/gcc/ada/libgnat/s-pack115.adb index ccca0e7..2b4c7dd 100644 --- a/gcc/ada/libgnat/s-pack115.adb +++ b/gcc/ada/libgnat/s-pack115.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_115 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 115 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_115 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_115; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_115; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_115; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_115; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_115; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_115; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_115; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_115; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_115 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_115 -- @@ -90,33 +373,47 @@ package body System.Pack_115 is N : Natural; Rev_SSO : Boolean) return Bits_115 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_115; @@ -130,32 +427,46 @@ package body System.Pack_115 is E : Bits_115; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_115; diff --git a/gcc/ada/libgnat/s-pack116.adb b/gcc/ada/libgnat/s-pack116.adb index 4787e6a..00e83b8 100644 --- a/gcc/ada/libgnat/s-pack116.adb +++ b/gcc/ada/libgnat/s-pack116.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_116 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 116 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_116 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_116; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_116 or SetU_116 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_116; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_116 or SetU_116 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_116; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_116 or SetU_116 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_116; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_116 or SetU_116 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_116; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_116 or SetU_116 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_116; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_116 or SetU_116 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_116; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_116 or SetU_116 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_116; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_116 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_116 or SetU_116 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_116 -- @@ -106,33 +501,47 @@ package body System.Pack_116 is N : Natural; Rev_SSO : Boolean) return Bits_116 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_116; @@ -145,33 +554,47 @@ package body System.Pack_116 is N : Natural; Rev_SSO : Boolean) return Bits_116 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_116; @@ -185,32 +608,46 @@ package body System.Pack_116 is E : Bits_116; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_116; @@ -225,32 +662,46 @@ package body System.Pack_116 is E : Bits_116; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_116; diff --git a/gcc/ada/libgnat/s-pack117.adb b/gcc/ada/libgnat/s-pack117.adb index b6940d1..e49a4ec 100644 --- a/gcc/ada/libgnat/s-pack117.adb +++ b/gcc/ada/libgnat/s-pack117.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_117 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 117 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_117 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_117; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_117; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_117; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_117; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_117; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_117; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_117; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_117; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_117 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_117 -- @@ -90,33 +373,47 @@ package body System.Pack_117 is N : Natural; Rev_SSO : Boolean) return Bits_117 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_117; @@ -130,32 +427,46 @@ package body System.Pack_117 is E : Bits_117; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_117; diff --git a/gcc/ada/libgnat/s-pack118.adb b/gcc/ada/libgnat/s-pack118.adb index 85aa2d5..67dcc0c 100644 --- a/gcc/ada/libgnat/s-pack118.adb +++ b/gcc/ada/libgnat/s-pack118.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_118 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 118 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_118 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_118; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_118 or SetU_118 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_118; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_118 or SetU_118 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_118; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_118 or SetU_118 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_118; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_118 or SetU_118 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_118; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_118 or SetU_118 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_118; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_118 or SetU_118 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_118; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_118 or SetU_118 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_118; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_118 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_118 or SetU_118 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_118 -- @@ -106,33 +501,47 @@ package body System.Pack_118 is N : Natural; Rev_SSO : Boolean) return Bits_118 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_118; @@ -145,33 +554,47 @@ package body System.Pack_118 is N : Natural; Rev_SSO : Boolean) return Bits_118 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_118; @@ -185,32 +608,46 @@ package body System.Pack_118 is E : Bits_118; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_118; @@ -225,32 +662,46 @@ package body System.Pack_118 is E : Bits_118; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_118; diff --git a/gcc/ada/libgnat/s-pack119.adb b/gcc/ada/libgnat/s-pack119.adb index 5351727..6351be2 100644 --- a/gcc/ada/libgnat/s-pack119.adb +++ b/gcc/ada/libgnat/s-pack119.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_119 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 119 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_119 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_119; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_119; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_119; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_119; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_119; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_119; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_119; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_119; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_119 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_119 -- @@ -90,33 +373,47 @@ package body System.Pack_119 is N : Natural; Rev_SSO : Boolean) return Bits_119 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_119; @@ -130,32 +427,46 @@ package body System.Pack_119 is E : Bits_119; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_119; diff --git a/gcc/ada/libgnat/s-pack12.adb b/gcc/ada/libgnat/s-pack12.adb index 6ff08c2..3ed31f1 100644 --- a/gcc/ada/libgnat/s-pack12.adb +++ b/gcc/ada/libgnat/s-pack12.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_12 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 12 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_12 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_12; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_12 or SetU_12 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_12; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_12 or SetU_12 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_12; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_12 or SetU_12 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_12; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_12 or SetU_12 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_12; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_12 or SetU_12 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_12; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_12 or SetU_12 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_12; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_12 or SetU_12 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_12; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_12 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_12 or SetU_12 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_12 -- @@ -106,33 +501,47 @@ package body System.Pack_12 is N : Natural; Rev_SSO : Boolean) return Bits_12 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_12; @@ -145,33 +554,47 @@ package body System.Pack_12 is N : Natural; Rev_SSO : Boolean) return Bits_12 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_12; @@ -185,32 +608,46 @@ package body System.Pack_12 is E : Bits_12; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_12; @@ -225,32 +662,46 @@ package body System.Pack_12 is E : Bits_12; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_12; diff --git a/gcc/ada/libgnat/s-pack120.adb b/gcc/ada/libgnat/s-pack120.adb index 9ba9099..2869e49 100644 --- a/gcc/ada/libgnat/s-pack120.adb +++ b/gcc/ada/libgnat/s-pack120.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_120 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 120 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_120 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_120; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_120 or SetU_120 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_120; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_120 or SetU_120 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_120; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_120 or SetU_120 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_120; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_120 or SetU_120 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_120; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_120 or SetU_120 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_120; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_120 or SetU_120 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_120; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_120 or SetU_120 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_120; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_120 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_120 or SetU_120 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_120 -- @@ -106,33 +501,47 @@ package body System.Pack_120 is N : Natural; Rev_SSO : Boolean) return Bits_120 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_120; @@ -145,33 +554,47 @@ package body System.Pack_120 is N : Natural; Rev_SSO : Boolean) return Bits_120 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_120; @@ -185,32 +608,46 @@ package body System.Pack_120 is E : Bits_120; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_120; @@ -225,32 +662,46 @@ package body System.Pack_120 is E : Bits_120; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_120; diff --git a/gcc/ada/libgnat/s-pack121.adb b/gcc/ada/libgnat/s-pack121.adb index c876c8d..f00afe8 100644 --- a/gcc/ada/libgnat/s-pack121.adb +++ b/gcc/ada/libgnat/s-pack121.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_121 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 121 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_121 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_121; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_121; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_121; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_121; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_121; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_121; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_121; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_121; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_121 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_121 -- @@ -90,33 +373,47 @@ package body System.Pack_121 is N : Natural; Rev_SSO : Boolean) return Bits_121 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_121; @@ -130,32 +427,46 @@ package body System.Pack_121 is E : Bits_121; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_121; diff --git a/gcc/ada/libgnat/s-pack122.adb b/gcc/ada/libgnat/s-pack122.adb index b118041..9e1bd4c 100644 --- a/gcc/ada/libgnat/s-pack122.adb +++ b/gcc/ada/libgnat/s-pack122.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_122 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 122 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_122 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_122; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_122 or SetU_122 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_122; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_122 or SetU_122 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_122; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_122 or SetU_122 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_122; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_122 or SetU_122 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_122; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_122 or SetU_122 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_122; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_122 or SetU_122 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_122; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_122 or SetU_122 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_122; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_122 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_122 or SetU_122 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_122 -- @@ -106,33 +501,47 @@ package body System.Pack_122 is N : Natural; Rev_SSO : Boolean) return Bits_122 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_122; @@ -145,33 +554,47 @@ package body System.Pack_122 is N : Natural; Rev_SSO : Boolean) return Bits_122 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_122; @@ -185,32 +608,46 @@ package body System.Pack_122 is E : Bits_122; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_122; @@ -225,32 +662,46 @@ package body System.Pack_122 is E : Bits_122; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_122; diff --git a/gcc/ada/libgnat/s-pack123.adb b/gcc/ada/libgnat/s-pack123.adb index db6ee28..720f0c4 100644 --- a/gcc/ada/libgnat/s-pack123.adb +++ b/gcc/ada/libgnat/s-pack123.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_123 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 123 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_123 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_123; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_123; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_123; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_123; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_123; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_123; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_123; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_123; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_123 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_123 -- @@ -90,33 +373,47 @@ package body System.Pack_123 is N : Natural; Rev_SSO : Boolean) return Bits_123 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_123; @@ -130,32 +427,46 @@ package body System.Pack_123 is E : Bits_123; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_123; diff --git a/gcc/ada/libgnat/s-pack124.adb b/gcc/ada/libgnat/s-pack124.adb index 8973af1..5073a62 100644 --- a/gcc/ada/libgnat/s-pack124.adb +++ b/gcc/ada/libgnat/s-pack124.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_124 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 124 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_124 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_124; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_124 or SetU_124 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_124; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_124 or SetU_124 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_124; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_124 or SetU_124 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_124; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_124 or SetU_124 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_124; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_124 or SetU_124 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_124; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_124 or SetU_124 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_124; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_124 or SetU_124 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_124; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_124 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_124 or SetU_124 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_124 -- @@ -106,33 +501,47 @@ package body System.Pack_124 is N : Natural; Rev_SSO : Boolean) return Bits_124 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_124; @@ -145,33 +554,47 @@ package body System.Pack_124 is N : Natural; Rev_SSO : Boolean) return Bits_124 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_124; @@ -185,32 +608,46 @@ package body System.Pack_124 is E : Bits_124; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_124; @@ -225,32 +662,46 @@ package body System.Pack_124 is E : Bits_124; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_124; diff --git a/gcc/ada/libgnat/s-pack125.adb b/gcc/ada/libgnat/s-pack125.adb index cd5e77e..9773d33 100644 --- a/gcc/ada/libgnat/s-pack125.adb +++ b/gcc/ada/libgnat/s-pack125.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_125 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 125 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_125 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_125; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_125; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_125; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_125; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_125; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_125; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_125; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_125; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_125 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_125 -- @@ -90,33 +373,47 @@ package body System.Pack_125 is N : Natural; Rev_SSO : Boolean) return Bits_125 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_125; @@ -130,32 +427,46 @@ package body System.Pack_125 is E : Bits_125; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_125; diff --git a/gcc/ada/libgnat/s-pack126.adb b/gcc/ada/libgnat/s-pack126.adb index 3aa0b24..fd38392e 100644 --- a/gcc/ada/libgnat/s-pack126.adb +++ b/gcc/ada/libgnat/s-pack126.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_126 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 126 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_126 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_126; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_126 or SetU_126 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_126; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_126 or SetU_126 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_126; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_126 or SetU_126 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_126; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_126 or SetU_126 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_126; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_126 or SetU_126 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_126; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_126 or SetU_126 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_126; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_126 or SetU_126 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_126; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_126 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_126 or SetU_126 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_126 -- @@ -106,33 +501,47 @@ package body System.Pack_126 is N : Natural; Rev_SSO : Boolean) return Bits_126 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_126; @@ -145,33 +554,47 @@ package body System.Pack_126 is N : Natural; Rev_SSO : Boolean) return Bits_126 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_126; @@ -185,32 +608,46 @@ package body System.Pack_126 is E : Bits_126; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_126; @@ -225,32 +662,46 @@ package body System.Pack_126 is E : Bits_126; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_126; diff --git a/gcc/ada/libgnat/s-pack127.adb b/gcc/ada/libgnat/s-pack127.adb index f85591e..54c6c6e 100644 --- a/gcc/ada/libgnat/s-pack127.adb +++ b/gcc/ada/libgnat/s-pack127.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_127 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 127 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_127 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_127; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_127; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_127; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_127; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_127; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_127; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_127; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_127; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_127 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_127 -- @@ -90,33 +373,47 @@ package body System.Pack_127 is N : Natural; Rev_SSO : Boolean) return Bits_127 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_127; @@ -130,32 +427,46 @@ package body System.Pack_127 is E : Bits_127; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_127; diff --git a/gcc/ada/libgnat/s-pack13.adb b/gcc/ada/libgnat/s-pack13.adb index 0623f9a..c867989 100644 --- a/gcc/ada/libgnat/s-pack13.adb +++ b/gcc/ada/libgnat/s-pack13.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_13 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 13 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_13 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_13; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_13; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_13; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_13; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_13; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_13; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_13; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_13; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_13 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_13 -- @@ -90,33 +373,47 @@ package body System.Pack_13 is N : Natural; Rev_SSO : Boolean) return Bits_13 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_13; @@ -130,32 +427,46 @@ package body System.Pack_13 is E : Bits_13; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_13; diff --git a/gcc/ada/libgnat/s-pack14.adb b/gcc/ada/libgnat/s-pack14.adb index c769d97..71fe2b0 100644 --- a/gcc/ada/libgnat/s-pack14.adb +++ b/gcc/ada/libgnat/s-pack14.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_14 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 14 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_14 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_14; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_14 or SetU_14 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_14; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_14 or SetU_14 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_14; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_14 or SetU_14 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_14; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_14 or SetU_14 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_14; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_14 or SetU_14 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_14; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_14 or SetU_14 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_14; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_14 or SetU_14 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_14; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_14 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_14 or SetU_14 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_14 -- @@ -106,33 +501,47 @@ package body System.Pack_14 is N : Natural; Rev_SSO : Boolean) return Bits_14 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_14; @@ -145,33 +554,47 @@ package body System.Pack_14 is N : Natural; Rev_SSO : Boolean) return Bits_14 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_14; @@ -185,32 +608,46 @@ package body System.Pack_14 is E : Bits_14; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_14; @@ -225,32 +662,46 @@ package body System.Pack_14 is E : Bits_14; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_14; diff --git a/gcc/ada/libgnat/s-pack15.adb b/gcc/ada/libgnat/s-pack15.adb index 70ff0f1..13fed1b 100644 --- a/gcc/ada/libgnat/s-pack15.adb +++ b/gcc/ada/libgnat/s-pack15.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_15 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 15 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_15 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_15; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_15; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_15; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_15; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_15; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_15; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_15; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_15; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_15 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_15 -- @@ -90,33 +373,47 @@ package body System.Pack_15 is N : Natural; Rev_SSO : Boolean) return Bits_15 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_15; @@ -130,32 +427,46 @@ package body System.Pack_15 is E : Bits_15; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_15; diff --git a/gcc/ada/libgnat/s-pack17.adb b/gcc/ada/libgnat/s-pack17.adb index 5347d0a..24c0aee 100644 --- a/gcc/ada/libgnat/s-pack17.adb +++ b/gcc/ada/libgnat/s-pack17.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_17 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 17 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_17 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_17; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_17; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_17; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_17; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_17; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_17; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_17; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_17; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_17 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_17 -- @@ -90,33 +373,47 @@ package body System.Pack_17 is N : Natural; Rev_SSO : Boolean) return Bits_17 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_17; @@ -130,32 +427,46 @@ package body System.Pack_17 is E : Bits_17; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_17; diff --git a/gcc/ada/libgnat/s-pack18.adb b/gcc/ada/libgnat/s-pack18.adb index b8a907c..845497b 100644 --- a/gcc/ada/libgnat/s-pack18.adb +++ b/gcc/ada/libgnat/s-pack18.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_18 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 18 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_18 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_18; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_18 or SetU_18 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_18; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_18 or SetU_18 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_18; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_18 or SetU_18 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_18; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_18 or SetU_18 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_18; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_18 or SetU_18 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_18; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_18 or SetU_18 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_18; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_18 or SetU_18 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_18; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_18 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_18 or SetU_18 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_18 -- @@ -106,33 +501,47 @@ package body System.Pack_18 is N : Natural; Rev_SSO : Boolean) return Bits_18 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_18; @@ -145,33 +554,47 @@ package body System.Pack_18 is N : Natural; Rev_SSO : Boolean) return Bits_18 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_18; @@ -185,32 +608,46 @@ package body System.Pack_18 is E : Bits_18; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_18; @@ -225,32 +662,46 @@ package body System.Pack_18 is E : Bits_18; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_18; diff --git a/gcc/ada/libgnat/s-pack19.adb b/gcc/ada/libgnat/s-pack19.adb index 5185380..7546624 100644 --- a/gcc/ada/libgnat/s-pack19.adb +++ b/gcc/ada/libgnat/s-pack19.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_19 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 19 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_19 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_19; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_19; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_19; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_19; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_19; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_19; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_19; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_19; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_19 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_19 -- @@ -90,33 +373,47 @@ package body System.Pack_19 is N : Natural; Rev_SSO : Boolean) return Bits_19 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_19; @@ -130,32 +427,46 @@ package body System.Pack_19 is E : Bits_19; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_19; diff --git a/gcc/ada/libgnat/s-pack20.adb b/gcc/ada/libgnat/s-pack20.adb index b5e0a67..f3db02e 100644 --- a/gcc/ada/libgnat/s-pack20.adb +++ b/gcc/ada/libgnat/s-pack20.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_20 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 20 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_20 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_20; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_20 or SetU_20 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_20; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_20 or SetU_20 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_20; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_20 or SetU_20 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_20; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_20 or SetU_20 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_20; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_20 or SetU_20 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_20; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_20 or SetU_20 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_20; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_20 or SetU_20 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_20; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_20 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_20 or SetU_20 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_20 -- @@ -106,33 +501,47 @@ package body System.Pack_20 is N : Natural; Rev_SSO : Boolean) return Bits_20 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_20; @@ -145,33 +554,47 @@ package body System.Pack_20 is N : Natural; Rev_SSO : Boolean) return Bits_20 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_20; @@ -185,32 +608,46 @@ package body System.Pack_20 is E : Bits_20; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_20; @@ -225,32 +662,46 @@ package body System.Pack_20 is E : Bits_20; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_20; diff --git a/gcc/ada/libgnat/s-pack21.adb b/gcc/ada/libgnat/s-pack21.adb index 8b98af8..22845e6 100644 --- a/gcc/ada/libgnat/s-pack21.adb +++ b/gcc/ada/libgnat/s-pack21.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_21 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 21 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_21 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_21; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_21; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_21; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_21; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_21; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_21; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_21; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_21; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_21 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_21 -- @@ -90,33 +373,47 @@ package body System.Pack_21 is N : Natural; Rev_SSO : Boolean) return Bits_21 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_21; @@ -130,32 +427,46 @@ package body System.Pack_21 is E : Bits_21; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_21; diff --git a/gcc/ada/libgnat/s-pack22.adb b/gcc/ada/libgnat/s-pack22.adb index 14e5226..c5d7042 100644 --- a/gcc/ada/libgnat/s-pack22.adb +++ b/gcc/ada/libgnat/s-pack22.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_22 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 22 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_22 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_22; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_22 or SetU_22 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_22; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_22 or SetU_22 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_22; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_22 or SetU_22 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_22; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_22 or SetU_22 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_22; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_22 or SetU_22 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_22; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_22 or SetU_22 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_22; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_22 or SetU_22 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_22; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_22 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_22 or SetU_22 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_22 -- @@ -106,33 +501,47 @@ package body System.Pack_22 is N : Natural; Rev_SSO : Boolean) return Bits_22 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_22; @@ -145,33 +554,47 @@ package body System.Pack_22 is N : Natural; Rev_SSO : Boolean) return Bits_22 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_22; @@ -185,32 +608,46 @@ package body System.Pack_22 is E : Bits_22; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_22; @@ -225,32 +662,46 @@ package body System.Pack_22 is E : Bits_22; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_22; diff --git a/gcc/ada/libgnat/s-pack23.adb b/gcc/ada/libgnat/s-pack23.adb index 7284a1b..ba4dc85 100644 --- a/gcc/ada/libgnat/s-pack23.adb +++ b/gcc/ada/libgnat/s-pack23.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_23 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 23 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_23 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_23; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_23; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_23; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_23; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_23; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_23; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_23; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_23; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_23 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_23 -- @@ -90,33 +373,47 @@ package body System.Pack_23 is N : Natural; Rev_SSO : Boolean) return Bits_23 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_23; @@ -130,32 +427,46 @@ package body System.Pack_23 is E : Bits_23; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_23; diff --git a/gcc/ada/libgnat/s-pack24.adb b/gcc/ada/libgnat/s-pack24.adb index b2c2a62..f25e3a6 100644 --- a/gcc/ada/libgnat/s-pack24.adb +++ b/gcc/ada/libgnat/s-pack24.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_24 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 24 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_24 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_24; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_24 or SetU_24 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_24; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_24 or SetU_24 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_24; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_24 or SetU_24 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_24; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_24 or SetU_24 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_24; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_24 or SetU_24 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_24; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_24 or SetU_24 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_24; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_24 or SetU_24 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_24; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_24 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_24 or SetU_24 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_24 -- @@ -106,33 +501,47 @@ package body System.Pack_24 is N : Natural; Rev_SSO : Boolean) return Bits_24 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_24; @@ -145,33 +554,47 @@ package body System.Pack_24 is N : Natural; Rev_SSO : Boolean) return Bits_24 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_24; @@ -185,32 +608,46 @@ package body System.Pack_24 is E : Bits_24; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_24; @@ -225,32 +662,46 @@ package body System.Pack_24 is E : Bits_24; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_24; diff --git a/gcc/ada/libgnat/s-pack25.adb b/gcc/ada/libgnat/s-pack25.adb index dd473d2..84475fd0 100644 --- a/gcc/ada/libgnat/s-pack25.adb +++ b/gcc/ada/libgnat/s-pack25.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_25 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 25 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_25 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_25; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_25; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_25; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_25; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_25; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_25; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_25; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_25; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_25 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_25 -- @@ -90,33 +373,47 @@ package body System.Pack_25 is N : Natural; Rev_SSO : Boolean) return Bits_25 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_25; @@ -130,32 +427,46 @@ package body System.Pack_25 is E : Bits_25; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_25; diff --git a/gcc/ada/libgnat/s-pack26.adb b/gcc/ada/libgnat/s-pack26.adb index 4a682b5..ff35349 100644 --- a/gcc/ada/libgnat/s-pack26.adb +++ b/gcc/ada/libgnat/s-pack26.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_26 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 26 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_26 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_26; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_26 or SetU_26 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_26; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_26 or SetU_26 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_26; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_26 or SetU_26 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_26; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_26 or SetU_26 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_26; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_26 or SetU_26 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_26; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_26 or SetU_26 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_26; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_26 or SetU_26 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_26; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_26 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_26 or SetU_26 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_26 -- @@ -106,33 +501,47 @@ package body System.Pack_26 is N : Natural; Rev_SSO : Boolean) return Bits_26 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_26; @@ -145,33 +554,47 @@ package body System.Pack_26 is N : Natural; Rev_SSO : Boolean) return Bits_26 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_26; @@ -185,32 +608,46 @@ package body System.Pack_26 is E : Bits_26; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_26; @@ -225,32 +662,46 @@ package body System.Pack_26 is E : Bits_26; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_26; diff --git a/gcc/ada/libgnat/s-pack27.adb b/gcc/ada/libgnat/s-pack27.adb index c0bc771..761406c 100644 --- a/gcc/ada/libgnat/s-pack27.adb +++ b/gcc/ada/libgnat/s-pack27.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_27 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 27 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_27 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_27; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_27; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_27; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_27; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_27; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_27; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_27; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_27; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_27 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_27 -- @@ -90,33 +373,47 @@ package body System.Pack_27 is N : Natural; Rev_SSO : Boolean) return Bits_27 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_27; @@ -130,32 +427,46 @@ package body System.Pack_27 is E : Bits_27; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_27; diff --git a/gcc/ada/libgnat/s-pack28.adb b/gcc/ada/libgnat/s-pack28.adb index be27c0e..5e9f3ef 100644 --- a/gcc/ada/libgnat/s-pack28.adb +++ b/gcc/ada/libgnat/s-pack28.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_28 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 28 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_28 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_28; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_28 or SetU_28 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_28; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_28 or SetU_28 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_28; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_28 or SetU_28 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_28; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_28 or SetU_28 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_28; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_28 or SetU_28 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_28; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_28 or SetU_28 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_28; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_28 or SetU_28 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_28; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_28 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_28 or SetU_28 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_28 -- @@ -106,33 +501,47 @@ package body System.Pack_28 is N : Natural; Rev_SSO : Boolean) return Bits_28 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_28; @@ -145,33 +554,47 @@ package body System.Pack_28 is N : Natural; Rev_SSO : Boolean) return Bits_28 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_28; @@ -185,32 +608,46 @@ package body System.Pack_28 is E : Bits_28; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_28; @@ -225,32 +662,46 @@ package body System.Pack_28 is E : Bits_28; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_28; diff --git a/gcc/ada/libgnat/s-pack29.adb b/gcc/ada/libgnat/s-pack29.adb index 2254b90..434c52b 100644 --- a/gcc/ada/libgnat/s-pack29.adb +++ b/gcc/ada/libgnat/s-pack29.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_29 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 29 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_29 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_29; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_29; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_29; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_29; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_29; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_29; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_29; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_29; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_29 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_29 -- @@ -90,33 +373,47 @@ package body System.Pack_29 is N : Natural; Rev_SSO : Boolean) return Bits_29 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_29; @@ -130,32 +427,46 @@ package body System.Pack_29 is E : Bits_29; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_29; diff --git a/gcc/ada/libgnat/s-pack30.adb b/gcc/ada/libgnat/s-pack30.adb index fa48a0a..14c525b 100644 --- a/gcc/ada/libgnat/s-pack30.adb +++ b/gcc/ada/libgnat/s-pack30.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_30 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 30 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_30 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_30; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_30 or SetU_30 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_30; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_30 or SetU_30 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_30; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_30 or SetU_30 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_30; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_30 or SetU_30 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_30; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_30 or SetU_30 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_30; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_30 or SetU_30 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_30; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_30 or SetU_30 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_30; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_30 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_30 or SetU_30 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_30 -- @@ -106,33 +501,47 @@ package body System.Pack_30 is N : Natural; Rev_SSO : Boolean) return Bits_30 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_30; @@ -145,33 +554,47 @@ package body System.Pack_30 is N : Natural; Rev_SSO : Boolean) return Bits_30 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_30; @@ -185,32 +608,46 @@ package body System.Pack_30 is E : Bits_30; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_30; @@ -225,32 +662,46 @@ package body System.Pack_30 is E : Bits_30; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_30; diff --git a/gcc/ada/libgnat/s-pack31.adb b/gcc/ada/libgnat/s-pack31.adb index 3234d43..4da5128 100644 --- a/gcc/ada/libgnat/s-pack31.adb +++ b/gcc/ada/libgnat/s-pack31.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_31 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 31 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_31 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_31; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_31; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_31; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_31; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_31; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_31; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_31; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_31; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_31 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_31 -- @@ -90,33 +373,47 @@ package body System.Pack_31 is N : Natural; Rev_SSO : Boolean) return Bits_31 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_31; @@ -130,32 +427,46 @@ package body System.Pack_31 is E : Bits_31; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_31; diff --git a/gcc/ada/libgnat/s-pack33.adb b/gcc/ada/libgnat/s-pack33.adb index 4b0aae8..ac7004a 100644 --- a/gcc/ada/libgnat/s-pack33.adb +++ b/gcc/ada/libgnat/s-pack33.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_33 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 33 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_33 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_33; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_33; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_33; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_33; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_33; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_33; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_33; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_33; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_33 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_33 -- @@ -90,33 +373,47 @@ package body System.Pack_33 is N : Natural; Rev_SSO : Boolean) return Bits_33 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_33; @@ -130,32 +427,46 @@ package body System.Pack_33 is E : Bits_33; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_33; diff --git a/gcc/ada/libgnat/s-pack34.adb b/gcc/ada/libgnat/s-pack34.adb index 2f8a348..18541c2 100644 --- a/gcc/ada/libgnat/s-pack34.adb +++ b/gcc/ada/libgnat/s-pack34.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_34 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 34 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_34 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_34; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_34 or SetU_34 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_34; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_34 or SetU_34 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_34; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_34 or SetU_34 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_34; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_34 or SetU_34 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_34; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_34 or SetU_34 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_34; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_34 or SetU_34 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_34; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_34 or SetU_34 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_34; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_34 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_34 or SetU_34 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_34 -- @@ -106,33 +501,47 @@ package body System.Pack_34 is N : Natural; Rev_SSO : Boolean) return Bits_34 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_34; @@ -145,33 +554,47 @@ package body System.Pack_34 is N : Natural; Rev_SSO : Boolean) return Bits_34 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_34; @@ -185,32 +608,46 @@ package body System.Pack_34 is E : Bits_34; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_34; @@ -225,32 +662,46 @@ package body System.Pack_34 is E : Bits_34; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_34; diff --git a/gcc/ada/libgnat/s-pack35.adb b/gcc/ada/libgnat/s-pack35.adb index 82608e1..6d02eca 100644 --- a/gcc/ada/libgnat/s-pack35.adb +++ b/gcc/ada/libgnat/s-pack35.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_35 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 35 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_35 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_35; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_35; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_35; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_35; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_35; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_35; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_35; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_35; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_35 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_35 -- @@ -90,33 +373,47 @@ package body System.Pack_35 is N : Natural; Rev_SSO : Boolean) return Bits_35 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_35; @@ -130,32 +427,46 @@ package body System.Pack_35 is E : Bits_35; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_35; diff --git a/gcc/ada/libgnat/s-pack36.adb b/gcc/ada/libgnat/s-pack36.adb index b395568..6ce7328 100644 --- a/gcc/ada/libgnat/s-pack36.adb +++ b/gcc/ada/libgnat/s-pack36.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_36 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 36 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_36 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_36; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_36 or SetU_36 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_36; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_36 or SetU_36 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_36; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_36 or SetU_36 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_36; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_36 or SetU_36 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_36; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_36 or SetU_36 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_36; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_36 or SetU_36 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_36; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_36 or SetU_36 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_36; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_36 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_36 or SetU_36 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_36 -- @@ -106,33 +501,47 @@ package body System.Pack_36 is N : Natural; Rev_SSO : Boolean) return Bits_36 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_36; @@ -145,33 +554,47 @@ package body System.Pack_36 is N : Natural; Rev_SSO : Boolean) return Bits_36 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_36; @@ -185,32 +608,46 @@ package body System.Pack_36 is E : Bits_36; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_36; @@ -225,32 +662,46 @@ package body System.Pack_36 is E : Bits_36; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_36; diff --git a/gcc/ada/libgnat/s-pack37.adb b/gcc/ada/libgnat/s-pack37.adb index 0f46635..373fe8d 100644 --- a/gcc/ada/libgnat/s-pack37.adb +++ b/gcc/ada/libgnat/s-pack37.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_37 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 37 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_37 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_37; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_37; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_37; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_37; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_37; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_37; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_37; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_37; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_37 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_37 -- @@ -90,33 +373,47 @@ package body System.Pack_37 is N : Natural; Rev_SSO : Boolean) return Bits_37 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_37; @@ -130,32 +427,46 @@ package body System.Pack_37 is E : Bits_37; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_37; diff --git a/gcc/ada/libgnat/s-pack38.adb b/gcc/ada/libgnat/s-pack38.adb index 97303c9..dcaaa4e 100644 --- a/gcc/ada/libgnat/s-pack38.adb +++ b/gcc/ada/libgnat/s-pack38.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_38 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 38 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_38 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_38; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_38 or SetU_38 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_38; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_38 or SetU_38 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_38; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_38 or SetU_38 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_38; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_38 or SetU_38 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_38; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_38 or SetU_38 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_38; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_38 or SetU_38 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_38; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_38 or SetU_38 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_38; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_38 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_38 or SetU_38 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_38 -- @@ -106,33 +501,47 @@ package body System.Pack_38 is N : Natural; Rev_SSO : Boolean) return Bits_38 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_38; @@ -145,33 +554,47 @@ package body System.Pack_38 is N : Natural; Rev_SSO : Boolean) return Bits_38 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_38; @@ -185,32 +608,46 @@ package body System.Pack_38 is E : Bits_38; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_38; @@ -225,32 +662,46 @@ package body System.Pack_38 is E : Bits_38; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_38; diff --git a/gcc/ada/libgnat/s-pack39.adb b/gcc/ada/libgnat/s-pack39.adb index e712ba0..8813705 100644 --- a/gcc/ada/libgnat/s-pack39.adb +++ b/gcc/ada/libgnat/s-pack39.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_39 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 39 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_39 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_39; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_39; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_39; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_39; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_39; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_39; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_39; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_39; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_39 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_39 -- @@ -90,33 +373,47 @@ package body System.Pack_39 is N : Natural; Rev_SSO : Boolean) return Bits_39 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_39; @@ -130,32 +427,46 @@ package body System.Pack_39 is E : Bits_39; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_39; diff --git a/gcc/ada/libgnat/s-pack40.adb b/gcc/ada/libgnat/s-pack40.adb index 44d8aa4..deac933 100644 --- a/gcc/ada/libgnat/s-pack40.adb +++ b/gcc/ada/libgnat/s-pack40.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_40 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 40 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_40 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_40; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_40 or SetU_40 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_40; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_40 or SetU_40 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_40; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_40 or SetU_40 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_40; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_40 or SetU_40 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_40; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_40 or SetU_40 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_40; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_40 or SetU_40 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_40; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_40 or SetU_40 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_40; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_40 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_40 or SetU_40 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_40 -- @@ -106,33 +501,47 @@ package body System.Pack_40 is N : Natural; Rev_SSO : Boolean) return Bits_40 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_40; @@ -145,33 +554,47 @@ package body System.Pack_40 is N : Natural; Rev_SSO : Boolean) return Bits_40 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_40; @@ -185,32 +608,46 @@ package body System.Pack_40 is E : Bits_40; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_40; @@ -225,32 +662,46 @@ package body System.Pack_40 is E : Bits_40; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_40; diff --git a/gcc/ada/libgnat/s-pack41.adb b/gcc/ada/libgnat/s-pack41.adb index cb7378a..782fa41 100644 --- a/gcc/ada/libgnat/s-pack41.adb +++ b/gcc/ada/libgnat/s-pack41.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_41 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 41 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_41 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_41; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_41; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_41; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_41; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_41; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_41; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_41; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_41; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_41 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_41 -- @@ -90,33 +373,47 @@ package body System.Pack_41 is N : Natural; Rev_SSO : Boolean) return Bits_41 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_41; @@ -130,32 +427,46 @@ package body System.Pack_41 is E : Bits_41; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_41; diff --git a/gcc/ada/libgnat/s-pack42.adb b/gcc/ada/libgnat/s-pack42.adb index 96b3881..a2a7ce0 100644 --- a/gcc/ada/libgnat/s-pack42.adb +++ b/gcc/ada/libgnat/s-pack42.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_42 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 42 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_42 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_42; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_42 or SetU_42 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_42; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_42 or SetU_42 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_42; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_42 or SetU_42 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_42; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_42 or SetU_42 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_42; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_42 or SetU_42 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_42; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_42 or SetU_42 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_42; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_42 or SetU_42 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_42; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_42 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_42 or SetU_42 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_42 -- @@ -106,33 +501,47 @@ package body System.Pack_42 is N : Natural; Rev_SSO : Boolean) return Bits_42 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_42; @@ -145,33 +554,47 @@ package body System.Pack_42 is N : Natural; Rev_SSO : Boolean) return Bits_42 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_42; @@ -185,32 +608,46 @@ package body System.Pack_42 is E : Bits_42; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_42; @@ -225,32 +662,46 @@ package body System.Pack_42 is E : Bits_42; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_42; diff --git a/gcc/ada/libgnat/s-pack43.adb b/gcc/ada/libgnat/s-pack43.adb index eb59a37..7dffd40 100644 --- a/gcc/ada/libgnat/s-pack43.adb +++ b/gcc/ada/libgnat/s-pack43.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_43 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 43 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_43 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_43; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_43; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_43; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_43; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_43; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_43; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_43; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_43; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_43 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_43 -- @@ -90,33 +373,47 @@ package body System.Pack_43 is N : Natural; Rev_SSO : Boolean) return Bits_43 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_43; @@ -130,32 +427,46 @@ package body System.Pack_43 is E : Bits_43; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_43; diff --git a/gcc/ada/libgnat/s-pack44.adb b/gcc/ada/libgnat/s-pack44.adb index f11db44..29c4920 100644 --- a/gcc/ada/libgnat/s-pack44.adb +++ b/gcc/ada/libgnat/s-pack44.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_44 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 44 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_44 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_44; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_44 or SetU_44 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_44; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_44 or SetU_44 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_44; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_44 or SetU_44 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_44; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_44 or SetU_44 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_44; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_44 or SetU_44 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_44; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_44 or SetU_44 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_44; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_44 or SetU_44 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_44; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_44 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_44 or SetU_44 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_44 -- @@ -106,33 +501,47 @@ package body System.Pack_44 is N : Natural; Rev_SSO : Boolean) return Bits_44 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_44; @@ -145,33 +554,47 @@ package body System.Pack_44 is N : Natural; Rev_SSO : Boolean) return Bits_44 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_44; @@ -185,32 +608,46 @@ package body System.Pack_44 is E : Bits_44; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_44; @@ -225,32 +662,46 @@ package body System.Pack_44 is E : Bits_44; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_44; diff --git a/gcc/ada/libgnat/s-pack45.adb b/gcc/ada/libgnat/s-pack45.adb index a880615..4cce386 100644 --- a/gcc/ada/libgnat/s-pack45.adb +++ b/gcc/ada/libgnat/s-pack45.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_45 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 45 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_45 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_45; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_45; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_45; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_45; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_45; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_45; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_45; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_45; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_45 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_45 -- @@ -90,33 +373,47 @@ package body System.Pack_45 is N : Natural; Rev_SSO : Boolean) return Bits_45 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_45; @@ -130,32 +427,46 @@ package body System.Pack_45 is E : Bits_45; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_45; diff --git a/gcc/ada/libgnat/s-pack46.adb b/gcc/ada/libgnat/s-pack46.adb index 586e97a..0ba0631 100644 --- a/gcc/ada/libgnat/s-pack46.adb +++ b/gcc/ada/libgnat/s-pack46.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_46 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 46 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_46 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_46; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_46 or SetU_46 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_46; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_46 or SetU_46 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_46; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_46 or SetU_46 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_46; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_46 or SetU_46 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_46; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_46 or SetU_46 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_46; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_46 or SetU_46 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_46; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_46 or SetU_46 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_46; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_46 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_46 or SetU_46 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_46 -- @@ -106,33 +501,47 @@ package body System.Pack_46 is N : Natural; Rev_SSO : Boolean) return Bits_46 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_46; @@ -145,33 +554,47 @@ package body System.Pack_46 is N : Natural; Rev_SSO : Boolean) return Bits_46 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_46; @@ -185,32 +608,46 @@ package body System.Pack_46 is E : Bits_46; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_46; @@ -225,32 +662,46 @@ package body System.Pack_46 is E : Bits_46; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_46; diff --git a/gcc/ada/libgnat/s-pack47.adb b/gcc/ada/libgnat/s-pack47.adb index d315c81..efd1e1e 100644 --- a/gcc/ada/libgnat/s-pack47.adb +++ b/gcc/ada/libgnat/s-pack47.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_47 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 47 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_47 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_47; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_47; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_47; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_47; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_47; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_47; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_47; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_47; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_47 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_47 -- @@ -90,33 +373,47 @@ package body System.Pack_47 is N : Natural; Rev_SSO : Boolean) return Bits_47 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_47; @@ -130,32 +427,46 @@ package body System.Pack_47 is E : Bits_47; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_47; diff --git a/gcc/ada/libgnat/s-pack48.adb b/gcc/ada/libgnat/s-pack48.adb index 247af83..a94c5fe 100644 --- a/gcc/ada/libgnat/s-pack48.adb +++ b/gcc/ada/libgnat/s-pack48.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_48 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 48 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_48 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_48; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_48 or SetU_48 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_48; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_48 or SetU_48 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_48; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_48 or SetU_48 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_48; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_48 or SetU_48 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_48; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_48 or SetU_48 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_48; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_48 or SetU_48 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_48; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_48 or SetU_48 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_48; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_48 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_48 or SetU_48 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_48 -- @@ -106,33 +501,47 @@ package body System.Pack_48 is N : Natural; Rev_SSO : Boolean) return Bits_48 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_48; @@ -145,33 +554,47 @@ package body System.Pack_48 is N : Natural; Rev_SSO : Boolean) return Bits_48 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_48; @@ -185,32 +608,46 @@ package body System.Pack_48 is E : Bits_48; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_48; @@ -225,32 +662,46 @@ package body System.Pack_48 is E : Bits_48; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_48; diff --git a/gcc/ada/libgnat/s-pack49.adb b/gcc/ada/libgnat/s-pack49.adb index a054313..5c8df0c 100644 --- a/gcc/ada/libgnat/s-pack49.adb +++ b/gcc/ada/libgnat/s-pack49.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_49 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 49 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_49 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_49; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_49; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_49; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_49; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_49; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_49; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_49; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_49; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_49 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_49 -- @@ -90,33 +373,47 @@ package body System.Pack_49 is N : Natural; Rev_SSO : Boolean) return Bits_49 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_49; @@ -130,32 +427,46 @@ package body System.Pack_49 is E : Bits_49; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_49; diff --git a/gcc/ada/libgnat/s-pack50.adb b/gcc/ada/libgnat/s-pack50.adb index c03c0cf2..769fe80 100644 --- a/gcc/ada/libgnat/s-pack50.adb +++ b/gcc/ada/libgnat/s-pack50.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_50 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 50 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_50 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_50; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_50 or SetU_50 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_50; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_50 or SetU_50 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_50; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_50 or SetU_50 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_50; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_50 or SetU_50 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_50; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_50 or SetU_50 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_50; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_50 or SetU_50 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_50; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_50 or SetU_50 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_50; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_50 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_50 or SetU_50 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_50 -- @@ -106,33 +501,47 @@ package body System.Pack_50 is N : Natural; Rev_SSO : Boolean) return Bits_50 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_50; @@ -145,33 +554,47 @@ package body System.Pack_50 is N : Natural; Rev_SSO : Boolean) return Bits_50 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_50; @@ -185,32 +608,46 @@ package body System.Pack_50 is E : Bits_50; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_50; @@ -225,32 +662,46 @@ package body System.Pack_50 is E : Bits_50; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_50; diff --git a/gcc/ada/libgnat/s-pack51.adb b/gcc/ada/libgnat/s-pack51.adb index 46abe28..89fb838 100644 --- a/gcc/ada/libgnat/s-pack51.adb +++ b/gcc/ada/libgnat/s-pack51.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_51 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 51 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_51 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_51; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_51; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_51; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_51; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_51; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_51; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_51; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_51; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_51 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_51 -- @@ -90,33 +373,47 @@ package body System.Pack_51 is N : Natural; Rev_SSO : Boolean) return Bits_51 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_51; @@ -130,32 +427,46 @@ package body System.Pack_51 is E : Bits_51; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_51; diff --git a/gcc/ada/libgnat/s-pack52.adb b/gcc/ada/libgnat/s-pack52.adb index 6cae3f7..d9bcf57 100644 --- a/gcc/ada/libgnat/s-pack52.adb +++ b/gcc/ada/libgnat/s-pack52.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_52 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 52 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_52 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_52; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_52 or SetU_52 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_52; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_52 or SetU_52 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_52; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_52 or SetU_52 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_52; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_52 or SetU_52 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_52; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_52 or SetU_52 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_52; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_52 or SetU_52 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_52; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_52 or SetU_52 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_52; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_52 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_52 or SetU_52 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_52 -- @@ -106,33 +501,47 @@ package body System.Pack_52 is N : Natural; Rev_SSO : Boolean) return Bits_52 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_52; @@ -145,33 +554,47 @@ package body System.Pack_52 is N : Natural; Rev_SSO : Boolean) return Bits_52 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_52; @@ -185,32 +608,46 @@ package body System.Pack_52 is E : Bits_52; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_52; @@ -225,32 +662,46 @@ package body System.Pack_52 is E : Bits_52; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_52; diff --git a/gcc/ada/libgnat/s-pack53.adb b/gcc/ada/libgnat/s-pack53.adb index 6a51fa6..58d3e7a 100644 --- a/gcc/ada/libgnat/s-pack53.adb +++ b/gcc/ada/libgnat/s-pack53.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_53 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 53 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_53 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_53; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_53; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_53; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_53; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_53; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_53; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_53; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_53; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_53 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_53 -- @@ -90,33 +373,47 @@ package body System.Pack_53 is N : Natural; Rev_SSO : Boolean) return Bits_53 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_53; @@ -130,32 +427,46 @@ package body System.Pack_53 is E : Bits_53; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_53; diff --git a/gcc/ada/libgnat/s-pack54.adb b/gcc/ada/libgnat/s-pack54.adb index 2cc4e9c..eedc057 100644 --- a/gcc/ada/libgnat/s-pack54.adb +++ b/gcc/ada/libgnat/s-pack54.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_54 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 54 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_54 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_54; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_54 or SetU_54 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_54; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_54 or SetU_54 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_54; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_54 or SetU_54 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_54; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_54 or SetU_54 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_54; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_54 or SetU_54 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_54; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_54 or SetU_54 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_54; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_54 or SetU_54 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_54; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_54 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_54 or SetU_54 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_54 -- @@ -106,33 +501,47 @@ package body System.Pack_54 is N : Natural; Rev_SSO : Boolean) return Bits_54 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_54; @@ -145,33 +554,47 @@ package body System.Pack_54 is N : Natural; Rev_SSO : Boolean) return Bits_54 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_54; @@ -185,32 +608,46 @@ package body System.Pack_54 is E : Bits_54; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_54; @@ -225,32 +662,46 @@ package body System.Pack_54 is E : Bits_54; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_54; diff --git a/gcc/ada/libgnat/s-pack55.adb b/gcc/ada/libgnat/s-pack55.adb index b1264c7..fafe954 100644 --- a/gcc/ada/libgnat/s-pack55.adb +++ b/gcc/ada/libgnat/s-pack55.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_55 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 55 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_55 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_55; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_55; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_55; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_55; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_55; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_55; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_55; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_55; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_55 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_55 -- @@ -90,33 +373,47 @@ package body System.Pack_55 is N : Natural; Rev_SSO : Boolean) return Bits_55 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_55; @@ -130,32 +427,46 @@ package body System.Pack_55 is E : Bits_55; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_55; diff --git a/gcc/ada/libgnat/s-pack56.adb b/gcc/ada/libgnat/s-pack56.adb index 100b348..c788d47 100644 --- a/gcc/ada/libgnat/s-pack56.adb +++ b/gcc/ada/libgnat/s-pack56.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_56 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 56 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_56 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_56; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_56 or SetU_56 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_56; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_56 or SetU_56 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_56; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_56 or SetU_56 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_56; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_56 or SetU_56 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_56; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_56 or SetU_56 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_56; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_56 or SetU_56 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_56; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_56 or SetU_56 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_56; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_56 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_56 or SetU_56 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_56 -- @@ -106,33 +501,47 @@ package body System.Pack_56 is N : Natural; Rev_SSO : Boolean) return Bits_56 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_56; @@ -145,33 +554,47 @@ package body System.Pack_56 is N : Natural; Rev_SSO : Boolean) return Bits_56 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_56; @@ -185,32 +608,46 @@ package body System.Pack_56 is E : Bits_56; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_56; @@ -225,32 +662,46 @@ package body System.Pack_56 is E : Bits_56; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_56; diff --git a/gcc/ada/libgnat/s-pack57.adb b/gcc/ada/libgnat/s-pack57.adb index 1056212..70b22ac 100644 --- a/gcc/ada/libgnat/s-pack57.adb +++ b/gcc/ada/libgnat/s-pack57.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_57 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 57 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_57 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_57; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_57; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_57; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_57; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_57; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_57; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_57; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_57; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_57 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_57 -- @@ -90,33 +373,47 @@ package body System.Pack_57 is N : Natural; Rev_SSO : Boolean) return Bits_57 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_57; @@ -130,32 +427,46 @@ package body System.Pack_57 is E : Bits_57; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_57; diff --git a/gcc/ada/libgnat/s-pack58.adb b/gcc/ada/libgnat/s-pack58.adb index c429d38..244c163 100644 --- a/gcc/ada/libgnat/s-pack58.adb +++ b/gcc/ada/libgnat/s-pack58.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_58 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 58 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_58 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_58; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_58 or SetU_58 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_58; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_58 or SetU_58 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_58; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_58 or SetU_58 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_58; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_58 or SetU_58 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_58; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_58 or SetU_58 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_58; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_58 or SetU_58 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_58; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_58 or SetU_58 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_58; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_58 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_58 or SetU_58 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_58 -- @@ -106,33 +501,47 @@ package body System.Pack_58 is N : Natural; Rev_SSO : Boolean) return Bits_58 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_58; @@ -145,33 +554,47 @@ package body System.Pack_58 is N : Natural; Rev_SSO : Boolean) return Bits_58 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_58; @@ -185,32 +608,46 @@ package body System.Pack_58 is E : Bits_58; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_58; @@ -225,32 +662,46 @@ package body System.Pack_58 is E : Bits_58; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_58; diff --git a/gcc/ada/libgnat/s-pack59.adb b/gcc/ada/libgnat/s-pack59.adb index fe304b9..c44931f 100644 --- a/gcc/ada/libgnat/s-pack59.adb +++ b/gcc/ada/libgnat/s-pack59.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_59 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 59 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_59 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_59; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_59; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_59; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_59; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_59; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_59; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_59; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_59; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_59 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_59 -- @@ -90,33 +373,47 @@ package body System.Pack_59 is N : Natural; Rev_SSO : Boolean) return Bits_59 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_59; @@ -130,32 +427,46 @@ package body System.Pack_59 is E : Bits_59; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_59; diff --git a/gcc/ada/libgnat/s-pack60.adb b/gcc/ada/libgnat/s-pack60.adb index 1d1422b..4be8ff8 100644 --- a/gcc/ada/libgnat/s-pack60.adb +++ b/gcc/ada/libgnat/s-pack60.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_60 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 60 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_60 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_60; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_60 or SetU_60 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_60; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_60 or SetU_60 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_60; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_60 or SetU_60 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_60; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_60 or SetU_60 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_60; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_60 or SetU_60 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_60; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_60 or SetU_60 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_60; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_60 or SetU_60 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_60; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_60 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_60 or SetU_60 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_60 -- @@ -106,33 +501,47 @@ package body System.Pack_60 is N : Natural; Rev_SSO : Boolean) return Bits_60 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_60; @@ -145,33 +554,47 @@ package body System.Pack_60 is N : Natural; Rev_SSO : Boolean) return Bits_60 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_60; @@ -185,32 +608,46 @@ package body System.Pack_60 is E : Bits_60; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_60; @@ -225,32 +662,46 @@ package body System.Pack_60 is E : Bits_60; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_60; diff --git a/gcc/ada/libgnat/s-pack61.adb b/gcc/ada/libgnat/s-pack61.adb index d744ff3..dd81dae 100644 --- a/gcc/ada/libgnat/s-pack61.adb +++ b/gcc/ada/libgnat/s-pack61.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_61 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 61 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_61 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_61; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_61; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_61; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_61; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_61; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_61; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_61; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_61; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_61 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_61 -- @@ -90,33 +373,47 @@ package body System.Pack_61 is N : Natural; Rev_SSO : Boolean) return Bits_61 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_61; @@ -130,32 +427,46 @@ package body System.Pack_61 is E : Bits_61; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_61; diff --git a/gcc/ada/libgnat/s-pack62.adb b/gcc/ada/libgnat/s-pack62.adb index d4745cf..00e846d 100644 --- a/gcc/ada/libgnat/s-pack62.adb +++ b/gcc/ada/libgnat/s-pack62.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_62 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 62 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_62 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_62; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_62 or SetU_62 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_62; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_62 or SetU_62 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_62; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_62 or SetU_62 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_62; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_62 or SetU_62 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_62; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_62 or SetU_62 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_62; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_62 or SetU_62 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_62; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_62 or SetU_62 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_62; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_62 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_62 or SetU_62 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_62 -- @@ -106,33 +501,47 @@ package body System.Pack_62 is N : Natural; Rev_SSO : Boolean) return Bits_62 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_62; @@ -145,33 +554,47 @@ package body System.Pack_62 is N : Natural; Rev_SSO : Boolean) return Bits_62 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_62; @@ -185,32 +608,46 @@ package body System.Pack_62 is E : Bits_62; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_62; @@ -225,32 +662,46 @@ package body System.Pack_62 is E : Bits_62; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_62; diff --git a/gcc/ada/libgnat/s-pack63.adb b/gcc/ada/libgnat/s-pack63.adb index 257fbab..ddaa42d 100644 --- a/gcc/ada/libgnat/s-pack63.adb +++ b/gcc/ada/libgnat/s-pack63.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_63 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 63 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_63 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_63; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_63; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_63; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_63; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_63; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_63; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_63; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_63; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_63 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_63 -- @@ -90,33 +373,47 @@ package body System.Pack_63 is N : Natural; Rev_SSO : Boolean) return Bits_63 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_63; @@ -130,32 +427,46 @@ package body System.Pack_63 is E : Bits_63; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_63; diff --git a/gcc/ada/libgnat/s-pack65.adb b/gcc/ada/libgnat/s-pack65.adb index 205b911..1f253dd 100644 --- a/gcc/ada/libgnat/s-pack65.adb +++ b/gcc/ada/libgnat/s-pack65.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_65 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 65 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_65 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_65; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_65; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_65; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_65; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_65; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_65; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_65; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_65; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_65 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_65 -- @@ -90,33 +373,47 @@ package body System.Pack_65 is N : Natural; Rev_SSO : Boolean) return Bits_65 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_65; @@ -130,32 +427,46 @@ package body System.Pack_65 is E : Bits_65; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_65; diff --git a/gcc/ada/libgnat/s-pack66.adb b/gcc/ada/libgnat/s-pack66.adb index cb95338..ba07451 100644 --- a/gcc/ada/libgnat/s-pack66.adb +++ b/gcc/ada/libgnat/s-pack66.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_66 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 66 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_66 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_66; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_66 or SetU_66 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_66; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_66 or SetU_66 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_66; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_66 or SetU_66 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_66; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_66 or SetU_66 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_66; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_66 or SetU_66 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_66; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_66 or SetU_66 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_66; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_66 or SetU_66 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_66; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_66 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_66 or SetU_66 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_66 -- @@ -106,33 +501,47 @@ package body System.Pack_66 is N : Natural; Rev_SSO : Boolean) return Bits_66 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_66; @@ -145,33 +554,47 @@ package body System.Pack_66 is N : Natural; Rev_SSO : Boolean) return Bits_66 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_66; @@ -185,32 +608,46 @@ package body System.Pack_66 is E : Bits_66; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_66; @@ -225,32 +662,46 @@ package body System.Pack_66 is E : Bits_66; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_66; diff --git a/gcc/ada/libgnat/s-pack67.adb b/gcc/ada/libgnat/s-pack67.adb index 194510a..7d09a43 100644 --- a/gcc/ada/libgnat/s-pack67.adb +++ b/gcc/ada/libgnat/s-pack67.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_67 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 67 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_67 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_67; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_67; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_67; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_67; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_67; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_67; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_67; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_67; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_67 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_67 -- @@ -90,33 +373,47 @@ package body System.Pack_67 is N : Natural; Rev_SSO : Boolean) return Bits_67 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_67; @@ -130,32 +427,46 @@ package body System.Pack_67 is E : Bits_67; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_67; diff --git a/gcc/ada/libgnat/s-pack68.adb b/gcc/ada/libgnat/s-pack68.adb index cf7043d..d274905 100644 --- a/gcc/ada/libgnat/s-pack68.adb +++ b/gcc/ada/libgnat/s-pack68.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_68 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 68 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_68 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_68; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_68 or SetU_68 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_68; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_68 or SetU_68 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_68; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_68 or SetU_68 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_68; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_68 or SetU_68 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_68; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_68 or SetU_68 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_68; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_68 or SetU_68 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_68; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_68 or SetU_68 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_68; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_68 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_68 or SetU_68 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_68 -- @@ -106,33 +501,47 @@ package body System.Pack_68 is N : Natural; Rev_SSO : Boolean) return Bits_68 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_68; @@ -145,33 +554,47 @@ package body System.Pack_68 is N : Natural; Rev_SSO : Boolean) return Bits_68 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_68; @@ -185,32 +608,46 @@ package body System.Pack_68 is E : Bits_68; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_68; @@ -225,32 +662,46 @@ package body System.Pack_68 is E : Bits_68; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_68; diff --git a/gcc/ada/libgnat/s-pack69.adb b/gcc/ada/libgnat/s-pack69.adb index 670e612..e105830 100644 --- a/gcc/ada/libgnat/s-pack69.adb +++ b/gcc/ada/libgnat/s-pack69.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_69 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 69 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_69 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_69; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_69; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_69; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_69; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_69; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_69; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_69; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_69; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_69 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_69 -- @@ -90,33 +373,47 @@ package body System.Pack_69 is N : Natural; Rev_SSO : Boolean) return Bits_69 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_69; @@ -130,32 +427,46 @@ package body System.Pack_69 is E : Bits_69; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_69; diff --git a/gcc/ada/libgnat/s-pack70.adb b/gcc/ada/libgnat/s-pack70.adb index aa320f6..39fa6dd 100644 --- a/gcc/ada/libgnat/s-pack70.adb +++ b/gcc/ada/libgnat/s-pack70.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_70 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 70 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_70 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_70; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_70 or SetU_70 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_70; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_70 or SetU_70 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_70; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_70 or SetU_70 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_70; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_70 or SetU_70 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_70; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_70 or SetU_70 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_70; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_70 or SetU_70 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_70; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_70 or SetU_70 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_70; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_70 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_70 or SetU_70 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_70 -- @@ -106,33 +501,47 @@ package body System.Pack_70 is N : Natural; Rev_SSO : Boolean) return Bits_70 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_70; @@ -145,33 +554,47 @@ package body System.Pack_70 is N : Natural; Rev_SSO : Boolean) return Bits_70 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_70; @@ -185,32 +608,46 @@ package body System.Pack_70 is E : Bits_70; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_70; @@ -225,32 +662,46 @@ package body System.Pack_70 is E : Bits_70; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_70; diff --git a/gcc/ada/libgnat/s-pack71.adb b/gcc/ada/libgnat/s-pack71.adb index 748a1c6..232a8de 100644 --- a/gcc/ada/libgnat/s-pack71.adb +++ b/gcc/ada/libgnat/s-pack71.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_71 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 71 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_71 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_71; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_71; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_71; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_71; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_71; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_71; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_71; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_71; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_71 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_71 -- @@ -90,33 +373,47 @@ package body System.Pack_71 is N : Natural; Rev_SSO : Boolean) return Bits_71 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_71; @@ -130,32 +427,46 @@ package body System.Pack_71 is E : Bits_71; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_71; diff --git a/gcc/ada/libgnat/s-pack72.adb b/gcc/ada/libgnat/s-pack72.adb index b2c463a..439f5ba 100644 --- a/gcc/ada/libgnat/s-pack72.adb +++ b/gcc/ada/libgnat/s-pack72.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_72 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 72 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_72 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_72; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_72 or SetU_72 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_72; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_72 or SetU_72 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_72; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_72 or SetU_72 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_72; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_72 or SetU_72 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_72; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_72 or SetU_72 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_72; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_72 or SetU_72 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_72; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_72 or SetU_72 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_72; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_72 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_72 or SetU_72 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_72 -- @@ -106,33 +501,47 @@ package body System.Pack_72 is N : Natural; Rev_SSO : Boolean) return Bits_72 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_72; @@ -145,33 +554,47 @@ package body System.Pack_72 is N : Natural; Rev_SSO : Boolean) return Bits_72 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_72; @@ -185,32 +608,46 @@ package body System.Pack_72 is E : Bits_72; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_72; @@ -225,32 +662,46 @@ package body System.Pack_72 is E : Bits_72; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_72; diff --git a/gcc/ada/libgnat/s-pack73.adb b/gcc/ada/libgnat/s-pack73.adb index 3abaebe..ddca1ea 100644 --- a/gcc/ada/libgnat/s-pack73.adb +++ b/gcc/ada/libgnat/s-pack73.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_73 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 73 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_73 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_73; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_73; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_73; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_73; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_73; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_73; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_73; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_73; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_73 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_73 -- @@ -90,33 +373,47 @@ package body System.Pack_73 is N : Natural; Rev_SSO : Boolean) return Bits_73 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_73; @@ -130,32 +427,46 @@ package body System.Pack_73 is E : Bits_73; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_73; diff --git a/gcc/ada/libgnat/s-pack74.adb b/gcc/ada/libgnat/s-pack74.adb index 2fe64bc..e157428 100644 --- a/gcc/ada/libgnat/s-pack74.adb +++ b/gcc/ada/libgnat/s-pack74.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_74 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 74 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_74 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_74; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_74 or SetU_74 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_74; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_74 or SetU_74 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_74; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_74 or SetU_74 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_74; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_74 or SetU_74 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_74; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_74 or SetU_74 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_74; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_74 or SetU_74 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_74; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_74 or SetU_74 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_74; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_74 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_74 or SetU_74 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_74 -- @@ -106,33 +501,47 @@ package body System.Pack_74 is N : Natural; Rev_SSO : Boolean) return Bits_74 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_74; @@ -145,33 +554,47 @@ package body System.Pack_74 is N : Natural; Rev_SSO : Boolean) return Bits_74 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_74; @@ -185,32 +608,46 @@ package body System.Pack_74 is E : Bits_74; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_74; @@ -225,32 +662,46 @@ package body System.Pack_74 is E : Bits_74; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_74; diff --git a/gcc/ada/libgnat/s-pack75.adb b/gcc/ada/libgnat/s-pack75.adb index d62afc9..45219c9 100644 --- a/gcc/ada/libgnat/s-pack75.adb +++ b/gcc/ada/libgnat/s-pack75.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_75 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 75 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_75 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_75; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_75; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_75; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_75; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_75; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_75; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_75; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_75; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_75 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_75 -- @@ -90,33 +373,47 @@ package body System.Pack_75 is N : Natural; Rev_SSO : Boolean) return Bits_75 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_75; @@ -130,32 +427,46 @@ package body System.Pack_75 is E : Bits_75; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_75; diff --git a/gcc/ada/libgnat/s-pack76.adb b/gcc/ada/libgnat/s-pack76.adb index 30c1596..86ce803 100644 --- a/gcc/ada/libgnat/s-pack76.adb +++ b/gcc/ada/libgnat/s-pack76.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_76 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 76 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_76 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_76; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_76 or SetU_76 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_76; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_76 or SetU_76 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_76; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_76 or SetU_76 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_76; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_76 or SetU_76 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_76; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_76 or SetU_76 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_76; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_76 or SetU_76 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_76; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_76 or SetU_76 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_76; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_76 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_76 or SetU_76 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_76 -- @@ -106,33 +501,47 @@ package body System.Pack_76 is N : Natural; Rev_SSO : Boolean) return Bits_76 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_76; @@ -145,33 +554,47 @@ package body System.Pack_76 is N : Natural; Rev_SSO : Boolean) return Bits_76 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_76; @@ -185,32 +608,46 @@ package body System.Pack_76 is E : Bits_76; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_76; @@ -225,32 +662,46 @@ package body System.Pack_76 is E : Bits_76; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_76; diff --git a/gcc/ada/libgnat/s-pack77.adb b/gcc/ada/libgnat/s-pack77.adb index eadc779..f4bb31b 100644 --- a/gcc/ada/libgnat/s-pack77.adb +++ b/gcc/ada/libgnat/s-pack77.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_77 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 77 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_77 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_77; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_77; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_77; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_77; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_77; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_77; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_77; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_77; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_77 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_77 -- @@ -90,33 +373,47 @@ package body System.Pack_77 is N : Natural; Rev_SSO : Boolean) return Bits_77 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_77; @@ -130,32 +427,46 @@ package body System.Pack_77 is E : Bits_77; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_77; diff --git a/gcc/ada/libgnat/s-pack78.adb b/gcc/ada/libgnat/s-pack78.adb index e5f1896..0b87996 100644 --- a/gcc/ada/libgnat/s-pack78.adb +++ b/gcc/ada/libgnat/s-pack78.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_78 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 78 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_78 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_78; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_78 or SetU_78 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_78; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_78 or SetU_78 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_78; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_78 or SetU_78 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_78; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_78 or SetU_78 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_78; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_78 or SetU_78 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_78; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_78 or SetU_78 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_78; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_78 or SetU_78 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_78; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_78 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_78 or SetU_78 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_78 -- @@ -106,33 +501,47 @@ package body System.Pack_78 is N : Natural; Rev_SSO : Boolean) return Bits_78 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_78; @@ -145,33 +554,47 @@ package body System.Pack_78 is N : Natural; Rev_SSO : Boolean) return Bits_78 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_78; @@ -185,32 +608,46 @@ package body System.Pack_78 is E : Bits_78; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_78; @@ -225,32 +662,46 @@ package body System.Pack_78 is E : Bits_78; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_78; diff --git a/gcc/ada/libgnat/s-pack79.adb b/gcc/ada/libgnat/s-pack79.adb index f2e52af..bcf854f 100644 --- a/gcc/ada/libgnat/s-pack79.adb +++ b/gcc/ada/libgnat/s-pack79.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_79 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 79 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_79 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_79; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_79; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_79; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_79; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_79; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_79; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_79; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_79; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_79 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_79 -- @@ -90,33 +373,47 @@ package body System.Pack_79 is N : Natural; Rev_SSO : Boolean) return Bits_79 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_79; @@ -130,32 +427,46 @@ package body System.Pack_79 is E : Bits_79; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_79; diff --git a/gcc/ada/libgnat/s-pack80.adb b/gcc/ada/libgnat/s-pack80.adb index 8668ad0..5769fe7 100644 --- a/gcc/ada/libgnat/s-pack80.adb +++ b/gcc/ada/libgnat/s-pack80.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_80 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 80 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_80 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_80; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_80 or SetU_80 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_80; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_80 or SetU_80 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_80; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_80 or SetU_80 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_80; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_80 or SetU_80 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_80; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_80 or SetU_80 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_80; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_80 or SetU_80 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_80; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_80 or SetU_80 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_80; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_80 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_80 or SetU_80 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_80 -- @@ -106,33 +501,47 @@ package body System.Pack_80 is N : Natural; Rev_SSO : Boolean) return Bits_80 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_80; @@ -145,33 +554,47 @@ package body System.Pack_80 is N : Natural; Rev_SSO : Boolean) return Bits_80 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_80; @@ -185,32 +608,46 @@ package body System.Pack_80 is E : Bits_80; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_80; @@ -225,32 +662,46 @@ package body System.Pack_80 is E : Bits_80; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_80; diff --git a/gcc/ada/libgnat/s-pack81.adb b/gcc/ada/libgnat/s-pack81.adb index 2100734..199a517 100644 --- a/gcc/ada/libgnat/s-pack81.adb +++ b/gcc/ada/libgnat/s-pack81.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_81 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 81 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_81 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_81; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_81; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_81; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_81; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_81; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_81; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_81; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_81; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_81 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_81 -- @@ -90,33 +373,47 @@ package body System.Pack_81 is N : Natural; Rev_SSO : Boolean) return Bits_81 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_81; @@ -130,32 +427,46 @@ package body System.Pack_81 is E : Bits_81; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_81; diff --git a/gcc/ada/libgnat/s-pack82.adb b/gcc/ada/libgnat/s-pack82.adb index 9e405a0..904bf6c 100644 --- a/gcc/ada/libgnat/s-pack82.adb +++ b/gcc/ada/libgnat/s-pack82.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_82 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 82 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_82 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_82; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_82 or SetU_82 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_82; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_82 or SetU_82 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_82; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_82 or SetU_82 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_82; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_82 or SetU_82 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_82; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_82 or SetU_82 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_82; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_82 or SetU_82 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_82; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_82 or SetU_82 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_82; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_82 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_82 or SetU_82 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_82 -- @@ -106,33 +501,47 @@ package body System.Pack_82 is N : Natural; Rev_SSO : Boolean) return Bits_82 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_82; @@ -145,33 +554,47 @@ package body System.Pack_82 is N : Natural; Rev_SSO : Boolean) return Bits_82 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_82; @@ -185,32 +608,46 @@ package body System.Pack_82 is E : Bits_82; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_82; @@ -225,32 +662,46 @@ package body System.Pack_82 is E : Bits_82; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_82; diff --git a/gcc/ada/libgnat/s-pack83.adb b/gcc/ada/libgnat/s-pack83.adb index 49420e6..8c37290 100644 --- a/gcc/ada/libgnat/s-pack83.adb +++ b/gcc/ada/libgnat/s-pack83.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_83 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 83 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_83 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_83; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_83; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_83; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_83; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_83; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_83; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_83; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_83; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_83 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_83 -- @@ -90,33 +373,47 @@ package body System.Pack_83 is N : Natural; Rev_SSO : Boolean) return Bits_83 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_83; @@ -130,32 +427,46 @@ package body System.Pack_83 is E : Bits_83; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_83; diff --git a/gcc/ada/libgnat/s-pack84.adb b/gcc/ada/libgnat/s-pack84.adb index a351194..0ebcd08 100644 --- a/gcc/ada/libgnat/s-pack84.adb +++ b/gcc/ada/libgnat/s-pack84.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_84 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 84 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_84 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_84; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_84 or SetU_84 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_84; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_84 or SetU_84 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_84; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_84 or SetU_84 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_84; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_84 or SetU_84 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_84; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_84 or SetU_84 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_84; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_84 or SetU_84 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_84; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_84 or SetU_84 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_84; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_84 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_84 or SetU_84 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_84 -- @@ -106,33 +501,47 @@ package body System.Pack_84 is N : Natural; Rev_SSO : Boolean) return Bits_84 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_84; @@ -145,33 +554,47 @@ package body System.Pack_84 is N : Natural; Rev_SSO : Boolean) return Bits_84 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_84; @@ -185,32 +608,46 @@ package body System.Pack_84 is E : Bits_84; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_84; @@ -225,32 +662,46 @@ package body System.Pack_84 is E : Bits_84; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_84; diff --git a/gcc/ada/libgnat/s-pack85.adb b/gcc/ada/libgnat/s-pack85.adb index b700e2e..2f1f886 100644 --- a/gcc/ada/libgnat/s-pack85.adb +++ b/gcc/ada/libgnat/s-pack85.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_85 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 85 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_85 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_85; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_85; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_85; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_85; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_85; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_85; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_85; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_85; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_85 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_85 -- @@ -90,33 +373,47 @@ package body System.Pack_85 is N : Natural; Rev_SSO : Boolean) return Bits_85 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_85; @@ -130,32 +427,46 @@ package body System.Pack_85 is E : Bits_85; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_85; diff --git a/gcc/ada/libgnat/s-pack86.adb b/gcc/ada/libgnat/s-pack86.adb index 3bf32d4..a738372 100644 --- a/gcc/ada/libgnat/s-pack86.adb +++ b/gcc/ada/libgnat/s-pack86.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_86 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 86 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_86 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_86; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_86 or SetU_86 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_86; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_86 or SetU_86 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_86; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_86 or SetU_86 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_86; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_86 or SetU_86 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_86; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_86 or SetU_86 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_86; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_86 or SetU_86 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_86; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_86 or SetU_86 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_86; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_86 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_86 or SetU_86 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_86 -- @@ -106,33 +501,47 @@ package body System.Pack_86 is N : Natural; Rev_SSO : Boolean) return Bits_86 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_86; @@ -145,33 +554,47 @@ package body System.Pack_86 is N : Natural; Rev_SSO : Boolean) return Bits_86 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_86; @@ -185,32 +608,46 @@ package body System.Pack_86 is E : Bits_86; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_86; @@ -225,32 +662,46 @@ package body System.Pack_86 is E : Bits_86; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_86; diff --git a/gcc/ada/libgnat/s-pack87.adb b/gcc/ada/libgnat/s-pack87.adb index 23e460b..5baaa07 100644 --- a/gcc/ada/libgnat/s-pack87.adb +++ b/gcc/ada/libgnat/s-pack87.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_87 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 87 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_87 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_87; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_87; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_87; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_87; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_87; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_87; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_87; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_87; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_87 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_87 -- @@ -90,33 +373,47 @@ package body System.Pack_87 is N : Natural; Rev_SSO : Boolean) return Bits_87 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_87; @@ -130,32 +427,46 @@ package body System.Pack_87 is E : Bits_87; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_87; diff --git a/gcc/ada/libgnat/s-pack88.adb b/gcc/ada/libgnat/s-pack88.adb index a17f248..b66836d 100644 --- a/gcc/ada/libgnat/s-pack88.adb +++ b/gcc/ada/libgnat/s-pack88.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_88 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 88 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_88 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_88; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_88 or SetU_88 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_88; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_88 or SetU_88 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_88; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_88 or SetU_88 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_88; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_88 or SetU_88 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_88; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_88 or SetU_88 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_88; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_88 or SetU_88 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_88; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_88 or SetU_88 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_88; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_88 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_88 or SetU_88 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_88 -- @@ -106,33 +501,47 @@ package body System.Pack_88 is N : Natural; Rev_SSO : Boolean) return Bits_88 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_88; @@ -145,33 +554,47 @@ package body System.Pack_88 is N : Natural; Rev_SSO : Boolean) return Bits_88 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_88; @@ -185,32 +608,46 @@ package body System.Pack_88 is E : Bits_88; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_88; @@ -225,32 +662,46 @@ package body System.Pack_88 is E : Bits_88; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_88; diff --git a/gcc/ada/libgnat/s-pack89.adb b/gcc/ada/libgnat/s-pack89.adb index 323005c..399dda5 100644 --- a/gcc/ada/libgnat/s-pack89.adb +++ b/gcc/ada/libgnat/s-pack89.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_89 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 89 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_89 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_89; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_89; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_89; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_89; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_89; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_89; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_89; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_89; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_89 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_89 -- @@ -90,33 +373,47 @@ package body System.Pack_89 is N : Natural; Rev_SSO : Boolean) return Bits_89 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_89; @@ -130,32 +427,46 @@ package body System.Pack_89 is E : Bits_89; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_89; diff --git a/gcc/ada/libgnat/s-pack90.adb b/gcc/ada/libgnat/s-pack90.adb index badcd3f..8ea7b07 100644 --- a/gcc/ada/libgnat/s-pack90.adb +++ b/gcc/ada/libgnat/s-pack90.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_90 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 90 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_90 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_90; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_90 or SetU_90 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_90; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_90 or SetU_90 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_90; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_90 or SetU_90 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_90; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_90 or SetU_90 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_90; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_90 or SetU_90 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_90; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_90 or SetU_90 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_90; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_90 or SetU_90 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_90; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_90 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_90 or SetU_90 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_90 -- @@ -106,33 +501,47 @@ package body System.Pack_90 is N : Natural; Rev_SSO : Boolean) return Bits_90 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_90; @@ -145,33 +554,47 @@ package body System.Pack_90 is N : Natural; Rev_SSO : Boolean) return Bits_90 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_90; @@ -185,32 +608,46 @@ package body System.Pack_90 is E : Bits_90; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_90; @@ -225,32 +662,46 @@ package body System.Pack_90 is E : Bits_90; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_90; diff --git a/gcc/ada/libgnat/s-pack91.adb b/gcc/ada/libgnat/s-pack91.adb index 5233fda..e62bb76 100644 --- a/gcc/ada/libgnat/s-pack91.adb +++ b/gcc/ada/libgnat/s-pack91.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_91 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 91 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_91 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_91; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_91; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_91; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_91; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_91; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_91; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_91; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_91; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_91 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_91 -- @@ -90,33 +373,47 @@ package body System.Pack_91 is N : Natural; Rev_SSO : Boolean) return Bits_91 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_91; @@ -130,32 +427,46 @@ package body System.Pack_91 is E : Bits_91; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_91; diff --git a/gcc/ada/libgnat/s-pack92.adb b/gcc/ada/libgnat/s-pack92.adb index 32f7aef..129013f 100644 --- a/gcc/ada/libgnat/s-pack92.adb +++ b/gcc/ada/libgnat/s-pack92.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_92 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 92 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_92 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_92; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_92 or SetU_92 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_92; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_92 or SetU_92 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_92; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_92 or SetU_92 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_92; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_92 or SetU_92 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_92; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_92 or SetU_92 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_92; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_92 or SetU_92 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_92; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_92 or SetU_92 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_92; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_92 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_92 or SetU_92 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_92 -- @@ -106,33 +501,47 @@ package body System.Pack_92 is N : Natural; Rev_SSO : Boolean) return Bits_92 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_92; @@ -145,33 +554,47 @@ package body System.Pack_92 is N : Natural; Rev_SSO : Boolean) return Bits_92 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_92; @@ -185,32 +608,46 @@ package body System.Pack_92 is E : Bits_92; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_92; @@ -225,32 +662,46 @@ package body System.Pack_92 is E : Bits_92; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_92; diff --git a/gcc/ada/libgnat/s-pack93.adb b/gcc/ada/libgnat/s-pack93.adb index 079b1be..ac33bf7 100644 --- a/gcc/ada/libgnat/s-pack93.adb +++ b/gcc/ada/libgnat/s-pack93.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_93 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 93 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_93 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_93; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_93; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_93; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_93; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_93; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_93; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_93; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_93; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_93 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_93 -- @@ -90,33 +373,47 @@ package body System.Pack_93 is N : Natural; Rev_SSO : Boolean) return Bits_93 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_93; @@ -130,32 +427,46 @@ package body System.Pack_93 is E : Bits_93; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_93; diff --git a/gcc/ada/libgnat/s-pack94.adb b/gcc/ada/libgnat/s-pack94.adb index 0964b37..9c82389 100644 --- a/gcc/ada/libgnat/s-pack94.adb +++ b/gcc/ada/libgnat/s-pack94.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_94 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 94 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_94 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_94; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_94 or SetU_94 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_94; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_94 or SetU_94 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_94; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_94 or SetU_94 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_94; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_94 or SetU_94 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_94; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_94 or SetU_94 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_94; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_94 or SetU_94 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_94; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_94 or SetU_94 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_94; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_94 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_94 or SetU_94 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_94 -- @@ -106,33 +501,47 @@ package body System.Pack_94 is N : Natural; Rev_SSO : Boolean) return Bits_94 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_94; @@ -145,33 +554,47 @@ package body System.Pack_94 is N : Natural; Rev_SSO : Boolean) return Bits_94 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_94; @@ -185,32 +608,46 @@ package body System.Pack_94 is E : Bits_94; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_94; @@ -225,32 +662,46 @@ package body System.Pack_94 is E : Bits_94; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_94; diff --git a/gcc/ada/libgnat/s-pack95.adb b/gcc/ada/libgnat/s-pack95.adb index c81c259..270b8cd 100644 --- a/gcc/ada/libgnat/s-pack95.adb +++ b/gcc/ada/libgnat/s-pack95.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_95 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 95 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_95 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_95; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_95; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_95; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_95; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_95; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_95; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_95; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_95; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_95 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_95 -- @@ -90,33 +373,47 @@ package body System.Pack_95 is N : Natural; Rev_SSO : Boolean) return Bits_95 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_95; @@ -130,32 +427,46 @@ package body System.Pack_95 is E : Bits_95; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_95; diff --git a/gcc/ada/libgnat/s-pack96.adb b/gcc/ada/libgnat/s-pack96.adb index 47bc025d..c6b8f68 100644 --- a/gcc/ada/libgnat/s-pack96.adb +++ b/gcc/ada/libgnat/s-pack96.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_96 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 96 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_96 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_96; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_96 or SetU_96 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_96; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_96 or SetU_96 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_96; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_96 or SetU_96 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_96; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_96 or SetU_96 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_96; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_96 or SetU_96 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_96; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_96 or SetU_96 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_96; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_96 or SetU_96 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_96; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_96 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_96 or SetU_96 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_96 -- @@ -106,33 +501,47 @@ package body System.Pack_96 is N : Natural; Rev_SSO : Boolean) return Bits_96 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_96; @@ -145,33 +554,47 @@ package body System.Pack_96 is N : Natural; Rev_SSO : Boolean) return Bits_96 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_96; @@ -185,32 +608,46 @@ package body System.Pack_96 is E : Bits_96; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_96; @@ -225,32 +662,46 @@ package body System.Pack_96 is E : Bits_96; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_96; diff --git a/gcc/ada/libgnat/s-pack97.adb b/gcc/ada/libgnat/s-pack97.adb index 737fc0f..7976432 100644 --- a/gcc/ada/libgnat/s-pack97.adb +++ b/gcc/ada/libgnat/s-pack97.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_97 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 97 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_97 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_97; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_97; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_97; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_97; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_97; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_97; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_97; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_97; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_97 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_97 -- @@ -90,33 +373,47 @@ package body System.Pack_97 is N : Natural; Rev_SSO : Boolean) return Bits_97 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_97; @@ -130,32 +427,46 @@ package body System.Pack_97 is E : Bits_97; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_97; diff --git a/gcc/ada/libgnat/s-pack98.adb b/gcc/ada/libgnat/s-pack98.adb index f6d3264..f0ce8bc 100644 --- a/gcc/ada/libgnat/s-pack98.adb +++ b/gcc/ada/libgnat/s-pack98.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_98 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 98 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,372 @@ package body System.Pack_98 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_98; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -- The following declarations are for the case where the address + -- passed to GetU_98 or SetU_98 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_98; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -- The following declarations are for the case where the address + -- passed to GetU_98 or SetU_98 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_98; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -- The following declarations are for the case where the address + -- passed to GetU_98 or SetU_98 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_98; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -- The following declarations are for the case where the address + -- passed to GetU_98 or SetU_98 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_98; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -- The following declarations are for the case where the address + -- passed to GetU_98 or SetU_98 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_98; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -- The following declarations are for the case where the address + -- passed to GetU_98 or SetU_98 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_98; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -- The following declarations are for the case where the address + -- passed to GetU_98 or SetU_98 is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_98; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,41 +456,41 @@ package body System.Pack_98 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); -- The following declarations are for the case where the address -- passed to GetU_98 or SetU_98 is not guaranteed to be aligned. -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); ------------ -- Get_98 -- @@ -106,33 +501,47 @@ package body System.Pack_98 is N : Natural; Rev_SSO : Boolean) return Bits_98 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_98; @@ -145,33 +554,47 @@ package body System.Pack_98 is N : Natural; Rev_SSO : Boolean) return Bits_98 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_98; @@ -185,32 +608,46 @@ package body System.Pack_98 is E : Bits_98; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_98; @@ -225,32 +662,46 @@ package body System.Pack_98 is E : Bits_98; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_98; diff --git a/gcc/ada/libgnat/s-pack99.adb b/gcc/ada/libgnat/s-pack99.adb index 9cc57f1..8621798 100644 --- a/gcc/ada/libgnat/s-pack99.adb +++ b/gcc/ada/libgnat/s-pack99.adb @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_99 is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words 99 bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,260 @@ package body System.Pack_99 is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_99; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_99; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_99; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_99; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_99; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_99; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_99; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_99; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +344,25 @@ package body System.Pack_99 is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); ------------ -- Get_99 -- @@ -90,33 +373,47 @@ package body System.Pack_99 is N : Natural; Rev_SSO : Boolean) return Bits_99 is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_99; @@ -130,32 +427,46 @@ package body System.Pack_99 is E : Bits_99; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_99; diff --git a/gcc/ada/s-pack.adb.tmpl b/gcc/ada/s-pack.adb.tmpl index 540c519..6596139 100644 --- a/gcc/ada/s-pack.adb.tmpl +++ b/gcc/ada/s-pack.adb.tmpl @@ -35,6 +35,40 @@ with System.Unsigned_Types; package body System.Pack_@@ is + -- The high-level idea of the implementation is to overlay a record + -- containing components of the same size as that of the component + -- of the array, in order words @@ bits, and to access the indexed + -- component of the array through the appropriate selected component + -- of the record. + + -- The record must be of a fixed size for technical reasons, so we + -- effectively overlay a series of contiguous records containing 8 + -- components (so that their size in bits is a multiple of a byte) + -- at the start of the array and access the component in the last + -- of them. However, this component in the last record may also be + -- mapped to the last component of the array, which means that the + -- generated code cannot safely access past it (or its last byte). + -- That's why the last record of the series is shortened, so the + -- accessed component is always the last component of the record. + + -- A (0) A (N) + -- | | + -- V V + -- --------------------------------------------------------------- + -- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + -- --------------------------------------------------------------- + -- + -- component K + -- | + -- V + -- --------------------------------------------------------- + -- | | | | | + -- --------------------------------------------------------- + -- | | | | + -- Cluster7 Cluster7 Cluster7 ClusterK + -- + -- where the number of Cluster7 is N / 8 and K is N mod 8. + subtype Bit_Order is System.Bit_Order; Reverse_Bit_Order : constant Bit_Order := Bit_Order'Val (1 - Bit_Order'Pos (System.Default_Bit_Order)); @@ -46,11 +80,386 @@ package body System.Pack_@@ is use type System.Storage_Elements.Storage_Offset; use type System.Unsigned_Types.Unsigned; - type Cluster is record + -------------- + -- Cluster0 -- + -------------- + + type Cluster0 is record + E0 : Bits_@@; + end record; + + for Cluster0 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + end record; + + for Cluster0'Size use Bits * (1 + 0); + + for Cluster0'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC0 is new Address_To_Access_Conversions (Cluster0); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster0 is new Cluster0 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0 is new Address_To_Access_Conversions (Rev_Cluster0); + +@even + -- The following declarations are for the case where the address + -- passed to GetU_@@ or SetU_@@ is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster0U is new Cluster0; + for Cluster0U'Alignment use 1; + + package AAC0U is new Address_To_Access_Conversions (Cluster0U); + + type Rev_Cluster0U is new Cluster0U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC0U is new Address_To_Access_Conversions (Rev_Cluster0U); + +@/even + -------------- + -- Cluster1 -- + -------------- + + type Cluster1 is record + E0, E1 : Bits_@@; + end record; + + for Cluster1 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + end record; + + for Cluster1'Size use Bits * (1 + 1); + + for Cluster1'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC1 is new Address_To_Access_Conversions (Cluster1); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster1 is new Cluster1 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1 is new Address_To_Access_Conversions (Rev_Cluster1); + +@even + -- The following declarations are for the case where the address + -- passed to GetU_@@ or SetU_@@ is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster1U is new Cluster1; + for Cluster1U'Alignment use 1; + + package AAC1U is new Address_To_Access_Conversions (Cluster1U); + + type Rev_Cluster1U is new Cluster1U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC1U is new Address_To_Access_Conversions (Rev_Cluster1U); + +@/even + -------------- + -- Cluster2 -- + -------------- + + type Cluster2 is record + E0, E1, E2 : Bits_@@; + end record; + + for Cluster2 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + end record; + + for Cluster2'Size use Bits * (1 + 2); + + for Cluster2'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC2 is new Address_To_Access_Conversions (Cluster2); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster2 is new Cluster2 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2 is new Address_To_Access_Conversions (Rev_Cluster2); + +@even + -- The following declarations are for the case where the address + -- passed to GetU_@@ or SetU_@@ is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster2U is new Cluster2; + for Cluster2U'Alignment use 1; + + package AAC2U is new Address_To_Access_Conversions (Cluster2U); + + type Rev_Cluster2U is new Cluster2U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC2U is new Address_To_Access_Conversions (Rev_Cluster2U); + +@/even + -------------- + -- Cluster3 -- + -------------- + + type Cluster3 is record + E0, E1, E2, E3 : Bits_@@; + end record; + + for Cluster3 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + end record; + + for Cluster3'Size use Bits * (1 + 3); + + for Cluster3'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC3 is new Address_To_Access_Conversions (Cluster3); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster3 is new Cluster3 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3 is new Address_To_Access_Conversions (Rev_Cluster3); + +@even + -- The following declarations are for the case where the address + -- passed to GetU_@@ or SetU_@@ is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster3U is new Cluster3; + for Cluster3U'Alignment use 1; + + package AAC3U is new Address_To_Access_Conversions (Cluster3U); + + type Rev_Cluster3U is new Cluster3U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC3U is new Address_To_Access_Conversions (Rev_Cluster3U); + +@/even + -------------- + -- Cluster4 -- + -------------- + + type Cluster4 is record + E0, E1, E2, E3, E4 : Bits_@@; + end record; + + for Cluster4 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + end record; + + for Cluster4'Size use Bits * (1 + 4); + + for Cluster4'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC4 is new Address_To_Access_Conversions (Cluster4); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster4 is new Cluster4 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4 is new Address_To_Access_Conversions (Rev_Cluster4); + +@even + -- The following declarations are for the case where the address + -- passed to GetU_@@ or SetU_@@ is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster4U is new Cluster4; + for Cluster4U'Alignment use 1; + + package AAC4U is new Address_To_Access_Conversions (Cluster4U); + + type Rev_Cluster4U is new Cluster4U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC4U is new Address_To_Access_Conversions (Rev_Cluster4U); + +@/even + -------------- + -- Cluster5 -- + -------------- + + type Cluster5 is record + E0, E1, E2, E3, E4, E5 : Bits_@@; + end record; + + for Cluster5 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + end record; + + for Cluster5'Size use Bits * (1 + 5); + + for Cluster5'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC5 is new Address_To_Access_Conversions (Cluster5); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster5 is new Cluster5 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5 is new Address_To_Access_Conversions (Rev_Cluster5); + +@even + -- The following declarations are for the case where the address + -- passed to GetU_@@ or SetU_@@ is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster5U is new Cluster5; + for Cluster5U'Alignment use 1; + + package AAC5U is new Address_To_Access_Conversions (Cluster5U); + + type Rev_Cluster5U is new Cluster5U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC5U is new Address_To_Access_Conversions (Rev_Cluster5U); + +@/even + -------------- + -- Cluster6 -- + -------------- + + type Cluster6 is record + E0, E1, E2, E3, E4, E5, E6 : Bits_@@; + end record; + + for Cluster6 use record + E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; + E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; + E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; + E3 at 0 range 3 * Bits .. 3 * Bits + Bits - 1; + E4 at 0 range 4 * Bits .. 4 * Bits + Bits - 1; + E5 at 0 range 5 * Bits .. 5 * Bits + Bits - 1; + E6 at 0 range 6 * Bits .. 6 * Bits + Bits - 1; + end record; + + for Cluster6'Size use Bits * (1 + 6); + + for Cluster6'Alignment use Integer'Min (Standard'Maximum_Alignment, + 1 + + 1 * Boolean'Pos (Bits mod 2 = 0) + + 2 * Boolean'Pos (Bits mod 4 = 0)); + -- Use maximum possible alignment, given the bit field size, since this + -- will result in the most efficient code possible for the field. + + package AAC6 is new Address_To_Access_Conversions (Cluster6); + -- We convert addresses to access values and dereference them instead of + -- directly using overlays in order to work around the implementation of + -- the RM 13.3(19) clause, which would pessimize the generated code. + + type Rev_Cluster6 is new Cluster6 + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6 is new Address_To_Access_Conversions (Rev_Cluster6); + +@even + -- The following declarations are for the case where the address + -- passed to GetU_@@ or SetU_@@ is not guaranteed to be aligned. + -- These routines are used when the packed array is itself a + -- component of a packed record, and therefore may not be aligned. + + type Cluster6U is new Cluster6; + for Cluster6U'Alignment use 1; + + package AAC6U is new Address_To_Access_Conversions (Cluster6U); + + type Rev_Cluster6U is new Cluster6U + with Bit_Order => Reverse_Bit_Order, + Scalar_Storage_Order => Reverse_Bit_Order; + + package Rev_AAC6U is new Address_To_Access_Conversions (Rev_Cluster6U); + +@/even + -------------- + -- Cluster7 -- + -------------- + + type Cluster7 is record E0, E1, E2, E3, E4, E5, E6, E7 : Bits_@@; end record; - for Cluster use record + for Cluster7 use record E0 at 0 range 0 * Bits .. 0 * Bits + Bits - 1; E1 at 0 range 1 * Bits .. 1 * Bits + Bits - 1; E2 at 0 range 2 * Bits .. 2 * Bits + Bits - 1; @@ -61,25 +470,25 @@ package body System.Pack_@@ is E7 at 0 range 7 * Bits .. 7 * Bits + Bits - 1; end record; - for Cluster'Size use Bits * 8; + for Cluster7'Size use Bits * (1 + 7); - for Cluster'Alignment use Integer'Min (Standard'Maximum_Alignment, + for Cluster7'Alignment use Integer'Min (Standard'Maximum_Alignment, 1 + 1 * Boolean'Pos (Bits mod 2 = 0) + 2 * Boolean'Pos (Bits mod 4 = 0)); -- Use maximum possible alignment, given the bit field size, since this -- will result in the most efficient code possible for the field. - package AAC is new Address_To_Access_Conversions (Cluster); + package AAC7 is new Address_To_Access_Conversions (Cluster7); -- We convert addresses to access values and dereference them instead of -- directly using overlays in order to work around the implementation of -- the RM 13.3(19) clause, which would pessimize the generated code. - type Rev_Cluster is new Cluster + type Rev_Cluster7 is new Cluster7 with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AAC is new Address_To_Access_Conversions (Rev_Cluster); + package Rev_AAC7 is new Address_To_Access_Conversions (Rev_Cluster7); @even -- The following declarations are for the case where the address @@ -87,16 +496,16 @@ package body System.Pack_@@ is -- These routines are used when the packed array is itself a -- component of a packed record, and therefore may not be aligned. - type ClusterU is new Cluster; - for ClusterU'Alignment use 1; + type Cluster7U is new Cluster7; + for Cluster7U'Alignment use 1; - package AACU is new Address_To_Access_Conversions (ClusterU); + package AAC7U is new Address_To_Access_Conversions (Cluster7U); - type Rev_ClusterU is new ClusterU + type Rev_Cluster7U is new Cluster7U with Bit_Order => Reverse_Bit_Order, Scalar_Storage_Order => Reverse_Bit_Order; - package Rev_AACU is new Address_To_Access_Conversions (Rev_ClusterU); + package Rev_AAC7U is new Address_To_Access_Conversions (Rev_Cluster7U); @/even ------------ @@ -108,33 +517,47 @@ package body System.Pack_@@ is N : Natural; Rev_SSO : Boolean) return Bits_@@ is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end Get_@@; @@ -148,33 +571,47 @@ package body System.Pack_@@ is N : Natural; Rev_SSO : Boolean) return Bits_@@ is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin return (if Rev_SSO then (case N07 (Uns (N) mod 8) is - when 0 => RC.E0, - when 1 => RC.E1, - when 2 => RC.E2, - when 3 => RC.E3, - when 4 => RC.E4, - when 5 => RC.E5, - when 6 => RC.E6, - when 7 => RC.E7) + when 0 => RC0.E0, + when 1 => RC1.E1, + when 2 => RC2.E2, + when 3 => RC3.E3, + when 4 => RC4.E4, + when 5 => RC5.E5, + when 6 => RC6.E6, + when 7 => RC7.E7) else (case N07 (Uns (N) mod 8) is - when 0 => C.E0, - when 1 => C.E1, - when 2 => C.E2, - when 3 => C.E3, - when 4 => C.E4, - when 5 => C.E5, - when 6 => C.E6, - when 7 => C.E7) + when 0 => C0.E0, + when 1 => C1.E1, + when 2 => C2.E2, + when 3 => C3.E3, + when 4 => C4.E4, + when 5 => C5.E5, + when 6 => C6.E6, + when 7 => C7.E7) ); end GetU_@@; @@ -189,32 +626,46 @@ package body System.Pack_@@ is E : Bits_@@; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AAC.Object_Pointer := AAC.To_Pointer (A); - RC : constant Rev_AAC.Object_Pointer := Rev_AAC.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0.Object_Pointer := AAC0.To_Pointer (A); + C1 : constant AAC1.Object_Pointer := AAC1.To_Pointer (A); + C2 : constant AAC2.Object_Pointer := AAC2.To_Pointer (A); + C3 : constant AAC3.Object_Pointer := AAC3.To_Pointer (A); + C4 : constant AAC4.Object_Pointer := AAC4.To_Pointer (A); + C5 : constant AAC5.Object_Pointer := AAC5.To_Pointer (A); + C6 : constant AAC6.Object_Pointer := AAC6.To_Pointer (A); + C7 : constant AAC7.Object_Pointer := AAC7.To_Pointer (A); + RC0 : constant Rev_AAC0.Object_Pointer := Rev_AAC0.To_Pointer (A); + RC1 : constant Rev_AAC1.Object_Pointer := Rev_AAC1.To_Pointer (A); + RC2 : constant Rev_AAC2.Object_Pointer := Rev_AAC2.To_Pointer (A); + RC3 : constant Rev_AAC3.Object_Pointer := Rev_AAC3.To_Pointer (A); + RC4 : constant Rev_AAC4.Object_Pointer := Rev_AAC4.To_Pointer (A); + RC5 : constant Rev_AAC5.Object_Pointer := Rev_AAC5.To_Pointer (A); + RC6 : constant Rev_AAC6.Object_Pointer := Rev_AAC6.To_Pointer (A); + RC7 : constant Rev_AAC7.Object_Pointer := Rev_AAC7.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end Set_@@; @@ -230,32 +681,46 @@ package body System.Pack_@@ is E : Bits_@@; Rev_SSO : Boolean) is - A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); - C : constant AACU.Object_Pointer := AACU.To_Pointer (A); - RC : constant Rev_AACU.Object_Pointer := Rev_AACU.To_Pointer (A); + A : constant System.Address := Arr + Bits * Ofs (Uns (N) / 8); + C0 : constant AAC0U.Object_Pointer := AAC0U.To_Pointer (A); + C1 : constant AAC1U.Object_Pointer := AAC1U.To_Pointer (A); + C2 : constant AAC2U.Object_Pointer := AAC2U.To_Pointer (A); + C3 : constant AAC3U.Object_Pointer := AAC3U.To_Pointer (A); + C4 : constant AAC4U.Object_Pointer := AAC4U.To_Pointer (A); + C5 : constant AAC5U.Object_Pointer := AAC5U.To_Pointer (A); + C6 : constant AAC6U.Object_Pointer := AAC6U.To_Pointer (A); + C7 : constant AAC7U.Object_Pointer := AAC7U.To_Pointer (A); + RC0 : constant Rev_AAC0U.Object_Pointer := Rev_AAC0U.To_Pointer (A); + RC1 : constant Rev_AAC1U.Object_Pointer := Rev_AAC1U.To_Pointer (A); + RC2 : constant Rev_AAC2U.Object_Pointer := Rev_AAC2U.To_Pointer (A); + RC3 : constant Rev_AAC3U.Object_Pointer := Rev_AAC3U.To_Pointer (A); + RC4 : constant Rev_AAC4U.Object_Pointer := Rev_AAC4U.To_Pointer (A); + RC5 : constant Rev_AAC5U.Object_Pointer := Rev_AAC5U.To_Pointer (A); + RC6 : constant Rev_AAC6U.Object_Pointer := Rev_AAC6U.To_Pointer (A); + RC7 : constant Rev_AAC7U.Object_Pointer := Rev_AAC7U.To_Pointer (A); begin if Rev_SSO then case N07 (Uns (N) mod 8) is - when 0 => RC.E0 := E; - when 1 => RC.E1 := E; - when 2 => RC.E2 := E; - when 3 => RC.E3 := E; - when 4 => RC.E4 := E; - when 5 => RC.E5 := E; - when 6 => RC.E6 := E; - when 7 => RC.E7 := E; + when 0 => RC0.E0 := E; + when 1 => RC1.E1 := E; + when 2 => RC2.E2 := E; + when 3 => RC3.E3 := E; + when 4 => RC4.E4 := E; + when 5 => RC5.E5 := E; + when 6 => RC6.E6 := E; + when 7 => RC7.E7 := E; end case; else case N07 (Uns (N) mod 8) is - when 0 => C.E0 := E; - when 1 => C.E1 := E; - when 2 => C.E2 := E; - when 3 => C.E3 := E; - when 4 => C.E4 := E; - when 5 => C.E5 := E; - when 6 => C.E6 := E; - when 7 => C.E7 := E; + when 0 => C0.E0 := E; + when 1 => C1.E1 := E; + when 2 => C2.E2 := E; + when 3 => C3.E3 := E; + when 4 => C4.E4 := E; + when 5 => C5.E5 := E; + when 6 => C6.E6 := E; + when 7 => C7.E7 := E; end case; end if; end SetU_@@; |