aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/libgnat/s-pack03.adb401
-rw-r--r--gcc/ada/libgnat/s-pack05.adb401
-rw-r--r--gcc/ada/libgnat/s-pack06.adb627
-rw-r--r--gcc/ada/libgnat/s-pack07.adb401
-rw-r--r--gcc/ada/libgnat/s-pack09.adb401
-rw-r--r--gcc/ada/libgnat/s-pack10.adb627
-rw-r--r--gcc/ada/libgnat/s-pack100.adb627
-rw-r--r--gcc/ada/libgnat/s-pack101.adb401
-rw-r--r--gcc/ada/libgnat/s-pack102.adb627
-rw-r--r--gcc/ada/libgnat/s-pack103.adb401
-rw-r--r--gcc/ada/libgnat/s-pack104.adb627
-rw-r--r--gcc/ada/libgnat/s-pack105.adb401
-rw-r--r--gcc/ada/libgnat/s-pack106.adb627
-rw-r--r--gcc/ada/libgnat/s-pack107.adb401
-rw-r--r--gcc/ada/libgnat/s-pack108.adb627
-rw-r--r--gcc/ada/libgnat/s-pack109.adb401
-rw-r--r--gcc/ada/libgnat/s-pack11.adb401
-rw-r--r--gcc/ada/libgnat/s-pack110.adb627
-rw-r--r--gcc/ada/libgnat/s-pack111.adb401
-rw-r--r--gcc/ada/libgnat/s-pack112.adb627
-rw-r--r--gcc/ada/libgnat/s-pack113.adb401
-rw-r--r--gcc/ada/libgnat/s-pack114.adb627
-rw-r--r--gcc/ada/libgnat/s-pack115.adb401
-rw-r--r--gcc/ada/libgnat/s-pack116.adb627
-rw-r--r--gcc/ada/libgnat/s-pack117.adb401
-rw-r--r--gcc/ada/libgnat/s-pack118.adb627
-rw-r--r--gcc/ada/libgnat/s-pack119.adb401
-rw-r--r--gcc/ada/libgnat/s-pack12.adb627
-rw-r--r--gcc/ada/libgnat/s-pack120.adb627
-rw-r--r--gcc/ada/libgnat/s-pack121.adb401
-rw-r--r--gcc/ada/libgnat/s-pack122.adb627
-rw-r--r--gcc/ada/libgnat/s-pack123.adb401
-rw-r--r--gcc/ada/libgnat/s-pack124.adb627
-rw-r--r--gcc/ada/libgnat/s-pack125.adb401
-rw-r--r--gcc/ada/libgnat/s-pack126.adb627
-rw-r--r--gcc/ada/libgnat/s-pack127.adb401
-rw-r--r--gcc/ada/libgnat/s-pack13.adb401
-rw-r--r--gcc/ada/libgnat/s-pack14.adb627
-rw-r--r--gcc/ada/libgnat/s-pack15.adb401
-rw-r--r--gcc/ada/libgnat/s-pack17.adb401
-rw-r--r--gcc/ada/libgnat/s-pack18.adb627
-rw-r--r--gcc/ada/libgnat/s-pack19.adb401
-rw-r--r--gcc/ada/libgnat/s-pack20.adb627
-rw-r--r--gcc/ada/libgnat/s-pack21.adb401
-rw-r--r--gcc/ada/libgnat/s-pack22.adb627
-rw-r--r--gcc/ada/libgnat/s-pack23.adb401
-rw-r--r--gcc/ada/libgnat/s-pack24.adb627
-rw-r--r--gcc/ada/libgnat/s-pack25.adb401
-rw-r--r--gcc/ada/libgnat/s-pack26.adb627
-rw-r--r--gcc/ada/libgnat/s-pack27.adb401
-rw-r--r--gcc/ada/libgnat/s-pack28.adb627
-rw-r--r--gcc/ada/libgnat/s-pack29.adb401
-rw-r--r--gcc/ada/libgnat/s-pack30.adb627
-rw-r--r--gcc/ada/libgnat/s-pack31.adb401
-rw-r--r--gcc/ada/libgnat/s-pack33.adb401
-rw-r--r--gcc/ada/libgnat/s-pack34.adb627
-rw-r--r--gcc/ada/libgnat/s-pack35.adb401
-rw-r--r--gcc/ada/libgnat/s-pack36.adb627
-rw-r--r--gcc/ada/libgnat/s-pack37.adb401
-rw-r--r--gcc/ada/libgnat/s-pack38.adb627
-rw-r--r--gcc/ada/libgnat/s-pack39.adb401
-rw-r--r--gcc/ada/libgnat/s-pack40.adb627
-rw-r--r--gcc/ada/libgnat/s-pack41.adb401
-rw-r--r--gcc/ada/libgnat/s-pack42.adb627
-rw-r--r--gcc/ada/libgnat/s-pack43.adb401
-rw-r--r--gcc/ada/libgnat/s-pack44.adb627
-rw-r--r--gcc/ada/libgnat/s-pack45.adb401
-rw-r--r--gcc/ada/libgnat/s-pack46.adb627
-rw-r--r--gcc/ada/libgnat/s-pack47.adb401
-rw-r--r--gcc/ada/libgnat/s-pack48.adb627
-rw-r--r--gcc/ada/libgnat/s-pack49.adb401
-rw-r--r--gcc/ada/libgnat/s-pack50.adb627
-rw-r--r--gcc/ada/libgnat/s-pack51.adb401
-rw-r--r--gcc/ada/libgnat/s-pack52.adb627
-rw-r--r--gcc/ada/libgnat/s-pack53.adb401
-rw-r--r--gcc/ada/libgnat/s-pack54.adb627
-rw-r--r--gcc/ada/libgnat/s-pack55.adb401
-rw-r--r--gcc/ada/libgnat/s-pack56.adb627
-rw-r--r--gcc/ada/libgnat/s-pack57.adb401
-rw-r--r--gcc/ada/libgnat/s-pack58.adb627
-rw-r--r--gcc/ada/libgnat/s-pack59.adb401
-rw-r--r--gcc/ada/libgnat/s-pack60.adb627
-rw-r--r--gcc/ada/libgnat/s-pack61.adb401
-rw-r--r--gcc/ada/libgnat/s-pack62.adb627
-rw-r--r--gcc/ada/libgnat/s-pack63.adb401
-rw-r--r--gcc/ada/libgnat/s-pack65.adb401
-rw-r--r--gcc/ada/libgnat/s-pack66.adb627
-rw-r--r--gcc/ada/libgnat/s-pack67.adb401
-rw-r--r--gcc/ada/libgnat/s-pack68.adb627
-rw-r--r--gcc/ada/libgnat/s-pack69.adb401
-rw-r--r--gcc/ada/libgnat/s-pack70.adb627
-rw-r--r--gcc/ada/libgnat/s-pack71.adb401
-rw-r--r--gcc/ada/libgnat/s-pack72.adb627
-rw-r--r--gcc/ada/libgnat/s-pack73.adb401
-rw-r--r--gcc/ada/libgnat/s-pack74.adb627
-rw-r--r--gcc/ada/libgnat/s-pack75.adb401
-rw-r--r--gcc/ada/libgnat/s-pack76.adb627
-rw-r--r--gcc/ada/libgnat/s-pack77.adb401
-rw-r--r--gcc/ada/libgnat/s-pack78.adb627
-rw-r--r--gcc/ada/libgnat/s-pack79.adb401
-rw-r--r--gcc/ada/libgnat/s-pack80.adb627
-rw-r--r--gcc/ada/libgnat/s-pack81.adb401
-rw-r--r--gcc/ada/libgnat/s-pack82.adb627
-rw-r--r--gcc/ada/libgnat/s-pack83.adb401
-rw-r--r--gcc/ada/libgnat/s-pack84.adb627
-rw-r--r--gcc/ada/libgnat/s-pack85.adb401
-rw-r--r--gcc/ada/libgnat/s-pack86.adb627
-rw-r--r--gcc/ada/libgnat/s-pack87.adb401
-rw-r--r--gcc/ada/libgnat/s-pack88.adb627
-rw-r--r--gcc/ada/libgnat/s-pack89.adb401
-rw-r--r--gcc/ada/libgnat/s-pack90.adb627
-rw-r--r--gcc/ada/libgnat/s-pack91.adb401
-rw-r--r--gcc/ada/libgnat/s-pack92.adb627
-rw-r--r--gcc/ada/libgnat/s-pack93.adb401
-rw-r--r--gcc/ada/libgnat/s-pack94.adb627
-rw-r--r--gcc/ada/libgnat/s-pack95.adb401
-rw-r--r--gcc/ada/libgnat/s-pack96.adb627
-rw-r--r--gcc/ada/libgnat/s-pack97.adb401
-rw-r--r--gcc/ada/libgnat/s-pack98.adb627
-rw-r--r--gcc/ada/libgnat/s-pack99.adb401
-rw-r--r--gcc/ada/s-pack.adb.tmpl641
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_@@;