diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2024-10-29 13:14:16 +0100 |
---|---|---|
committer | Marc Poulhiès <dkm@gcc.gnu.org> | 2024-11-12 14:05:47 +0100 |
commit | ab3106747e3c12405f754017a5441db45aa97e6a (patch) | |
tree | 4280644ff97fe041bfafc328661d367dd494d519 /gcc/ada/libgnat/s-pack108.adb | |
parent | fbbfad022c2f5bc6b481b41bd32faa278e343474 (diff) | |
download | gcc-ab3106747e3c12405f754017a5441db45aa97e6a.zip gcc-ab3106747e3c12405f754017a5441db45aa97e6a.tar.gz gcc-ab3106747e3c12405f754017a5441db45aa97e6a.tar.bz2 |
ada: Make sure not to access past the end of bit-packed arrays
The code generated for the routines of the run-time library that implement
support for bit-packed arrays with non-power-of-2 component sizes turns out
to be problematic for the Address Sanitizer and the CHERI architecture, as
it may access past the end of bit-packed arrays in specific cases.
No functional changes.
gcc/ada/ChangeLog:
* s-pack.adb.tmpl: Add '7' suffix to all existing constructs and
add variants with suffixes ranging from '0' to '6'.
(Get_@@): Dereference the address as a record object whose accessed
component is always the last.
(GetU_@@): Likewise.
(Set_@@): Likewise.
(SetU_@@): Likewise.
* libgnat/s-pack03.adb: Regenerate.
* libgnat/s-pack05.adb: Likewise.
* libgnat/s-pack06.adb: Likewise.
* libgnat/s-pack07.adb: Likewise.
* libgnat/s-pack09.adb: Likewise.
* libgnat/s-pack10.adb: Likewise.
* libgnat/s-pack100.adb: Likewise.
* libgnat/s-pack101.adb: Likewise.
* libgnat/s-pack102.adb: Likewise.
* libgnat/s-pack103.adb: Likewise.
* libgnat/s-pack104.adb: Likewise.
* libgnat/s-pack105.adb: Likewise.
* libgnat/s-pack106.adb: Likewise.
* libgnat/s-pack107.adb: Likewise.
* libgnat/s-pack108.adb: Likewise.
* libgnat/s-pack109.adb: Likewise.
* libgnat/s-pack11.adb: Likewise.
* libgnat/s-pack110.adb: Likewise.
* libgnat/s-pack111.adb: Likewise.
* libgnat/s-pack112.adb: Likewise.
* libgnat/s-pack113.adb: Likewise.
* libgnat/s-pack114.adb: Likewise.
* libgnat/s-pack115.adb: Likewise.
* libgnat/s-pack116.adb: Likewise.
* libgnat/s-pack117.adb: Likewise.
* libgnat/s-pack118.adb: Likewise.
* libgnat/s-pack119.adb: Likewise.
* libgnat/s-pack12.adb: Likewise.
* libgnat/s-pack120.adb: Likewise.
* libgnat/s-pack121.adb: Likewise.
* libgnat/s-pack122.adb: Likewise.
* libgnat/s-pack123.adb: Likewise.
* libgnat/s-pack124.adb: Likewise.
* libgnat/s-pack125.adb: Likewise.
* libgnat/s-pack126.adb: Likewise.
* libgnat/s-pack127.adb: Likewise.
* libgnat/s-pack13.adb: Likewise.
* libgnat/s-pack14.adb: Likewise.
* libgnat/s-pack15.adb: Likewise.
* libgnat/s-pack17.adb: Likewise.
* libgnat/s-pack18.adb: Likewise.
* libgnat/s-pack19.adb: Likewise.
* libgnat/s-pack20.adb: Likewise.
* libgnat/s-pack21.adb: Likewise.
* libgnat/s-pack22.adb: Likewise.
* libgnat/s-pack23.adb: Likewise.
* libgnat/s-pack24.adb: Likewise.
* libgnat/s-pack25.adb: Likewise.
* libgnat/s-pack26.adb: Likewise.
* libgnat/s-pack27.adb: Likewise.
* libgnat/s-pack28.adb: Likewise.
* libgnat/s-pack29.adb: Likewise.
* libgnat/s-pack30.adb: Likewise.
* libgnat/s-pack31.adb: Likewise.
* libgnat/s-pack33.adb: Likewise.
* libgnat/s-pack34.adb: Likewise.
* libgnat/s-pack35.adb: Likewise.
* libgnat/s-pack36.adb: Likewise.
* libgnat/s-pack37.adb: Likewise.
* libgnat/s-pack38.adb: Likewise.
* libgnat/s-pack39.adb: Likewise.
* libgnat/s-pack40.adb: Likewise.
* libgnat/s-pack41.adb: Likewise.
* libgnat/s-pack42.adb: Likewise.
* libgnat/s-pack43.adb: Likewise.
* libgnat/s-pack44.adb: Likewise.
* libgnat/s-pack45.adb: Likewise.
* libgnat/s-pack46.adb: Likewise.
* libgnat/s-pack47.adb: Likewise.
* libgnat/s-pack48.adb: Likewise.
* libgnat/s-pack49.adb: Likewise.
* libgnat/s-pack50.adb: Likewise.
* libgnat/s-pack51.adb: Likewise.
* libgnat/s-pack52.adb: Likewise.
* libgnat/s-pack53.adb: Likewise.
* libgnat/s-pack54.adb: Likewise.
* libgnat/s-pack55.adb: Likewise.
* libgnat/s-pack56.adb: Likewise.
* libgnat/s-pack57.adb: Likewise.
* libgnat/s-pack58.adb: Likewise.
* libgnat/s-pack59.adb: Likewise.
* libgnat/s-pack60.adb: Likewise.
* libgnat/s-pack61.adb: Likewise.
* libgnat/s-pack62.adb: Likewise.
* libgnat/s-pack63.adb: Likewise.
* libgnat/s-pack65.adb: Likewise.
* libgnat/s-pack66.adb: Likewise.
* libgnat/s-pack67.adb: Likewise.
* libgnat/s-pack68.adb: Likewise.
* libgnat/s-pack69.adb: Likewise.
* libgnat/s-pack70.adb: Likewise.
* libgnat/s-pack71.adb: Likewise.
* libgnat/s-pack72.adb: Likewise.
* libgnat/s-pack73.adb: Likewise.
* libgnat/s-pack74.adb: Likewise.
* libgnat/s-pack75.adb: Likewise.
* libgnat/s-pack76.adb: Likewise.
* libgnat/s-pack77.adb: Likewise.
* libgnat/s-pack78.adb: Likewise.
* libgnat/s-pack79.adb: Likewise.
* libgnat/s-pack80.adb: Likewise.
* libgnat/s-pack81.adb: Likewise.
* libgnat/s-pack82.adb: Likewise.
* libgnat/s-pack83.adb: Likewise.
* libgnat/s-pack84.adb: Likewise.
* libgnat/s-pack85.adb: Likewise.
* libgnat/s-pack86.adb: Likewise.
* libgnat/s-pack87.adb: Likewise.
* libgnat/s-pack88.adb: Likewise.
* libgnat/s-pack89.adb: Likewise.
* libgnat/s-pack90.adb: Likewise.
* libgnat/s-pack91.adb: Likewise.
* libgnat/s-pack92.adb: Likewise.
* libgnat/s-pack93.adb: Likewise.
* libgnat/s-pack94.adb: Likewise.
* libgnat/s-pack95.adb: Likewise.
* libgnat/s-pack96.adb: Likewise.
* libgnat/s-pack97.adb: Likewise.
* libgnat/s-pack98.adb: Likewise.
* libgnat/s-pack99.adb: Likewise.
Diffstat (limited to 'gcc/ada/libgnat/s-pack108.adb')
-rw-r--r-- | gcc/ada/libgnat/s-pack108.adb | 627 |
1 files changed, 539 insertions, 88 deletions
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; |