diff options
author | Bob Duff <duff@adacore.com> | 2019-08-21 08:30:53 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2019-08-21 08:30:53 +0000 |
commit | abdeafa67a8ec7c99830fd5039d38168abba52a9 (patch) | |
tree | 991871518d9927868f87a35320792b8c36f34d67 /gcc/ada/libgnat/s-bituti.ads | |
parent | a1fda1e8752ecbf3b109d851e4a7d7d04159170e (diff) | |
download | gcc-abdeafa67a8ec7c99830fd5039d38168abba52a9.zip gcc-abdeafa67a8ec7c99830fd5039d38168abba52a9.tar.gz gcc-abdeafa67a8ec7c99830fd5039d38168abba52a9.tar.bz2 |
[Ada] Add the System.Bitfield_Utils runtime unit
2019-08-21 Bob Duff <duff@adacore.com>
gcc/ada/
* Makefile.rtl (GNATRTL_NONTASKING_OBJS): Add s-bitutil.o and
s-biutin.o.
* exp_ch5.adb (Expand_Assign_Array_Bitfield): New function to
generate a call to Copy_Bitfield. This is disabled for now.
(Expand_Assign_Array_Loop_Or_Bitfield): New function to decide
whether to call Expand_Assign_Array_Bitfield.
(Expand_Assign_Array): Call Expand_Assign_Array_Loop_Or_Bitfield
instead of Expand_Assign_Array_Loop.
* libgnat/s-bitfie.ads, libgnat/s-bituti.adb,
libgnat/s-bituti.ads: New units.
* rtsfind.ads: Add enum literals for accessing Copy_Bitfield.
From-SVN: r274785
Diffstat (limited to 'gcc/ada/libgnat/s-bituti.ads')
-rw-r--r-- | gcc/ada/libgnat/s-bituti.ads | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/gcc/ada/libgnat/s-bituti.ads b/gcc/ada/libgnat/s-bituti.ads new file mode 100644 index 0000000..1e446c1 --- /dev/null +++ b/gcc/ada/libgnat/s-bituti.ads @@ -0,0 +1,132 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT RUN-TIME COMPONENTS -- +-- -- +-- S Y S T E M . B I T F I E L D _ U T I L S -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2019, Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- <http://www.gnu.org/licenses/>. -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +package System.Bitfield_Utils is + + -- This package provides a procedure for copying arbitrarily large and + -- arbitrarily bit-aligned bit fields. + + -- Type Val is used to represent small bit fields. Val_2 represents a + -- contiguous pair of Vals. Val_2'Alignment is half of its size in bytes, + -- which is likely not the natural alignment. This is done to ensure that + -- any bit field that fits in a Val can fit in an aligned Val_2, starting + -- somewhere in the first half, and possibly crossing over into the second + -- half. This allows us to isolate a Val value by shifting and masking the + -- Val_2. + -- + -- Val can be 8, 16, or 32 bits; larger values are more efficient. It can't + -- be 64 bits, because we need Val_2 to be a double-wide shiftable type, + -- and 128 bits is not supported. Instantiating with an 8-bit Val is useful + -- for testing and debugging; 32 bits should be used for production. + -- + -- We use modular types here, not because we want modular arithmetic, but + -- so we can do shifting and masking. The actual for Val_2 should have + -- pragma Provide_Shift_Operators, so that the Shift_Left and Shift_Right + -- intrinsics can be passed in. It is impossible to put that pragma on a + -- generic formal, or on a type derived from a generic formal, so they have + -- to be passed in. + -- + -- Endian indicates whether we're on little-endian or big-endian machine. + + pragma Elaborate_Body; + + Little : constant Bit_Order := Low_Order_First; + Big : constant Bit_Order := High_Order_First; + + generic + type Val is mod <>; + type Val_2 is mod <>; + + with function Shift_Left + (Value : Val_2; + Amount : Natural) return Val_2 is <>; + + with function Shift_Right + (Value : Val_2; + Amount : Natural) return Val_2 is <>; + + Endian : Bit_Order := Default_Bit_Order; + + package G is + -- Assert that Val has one of the allowed sizes, and that Val_2 is twice + -- that. + + pragma Assert (Val'Size in 8 | 16 | 32); + pragma Assert (Val_2'Size = Val'Size * 2); + + -- Assert that both are aligned the same, to the size in bytes of Val + -- (not Val_2). + + pragma Assert (Val'Alignment = Val'Size / Storage_Unit); + pragma Assert (Val_2'Alignment = Val'Alignment); + + type Val_Array is array (Positive range <>) of Val; + + -- It might make more sense to have: + -- subtype Val is Val_2 range 0 .. 2**Val'Size - 1; + -- But then GNAT gets the component size of Val_Array wrong. + + pragma Assert (Val_Array'Alignment = Val'Alignment); + pragma Assert (Val_Array'Component_Size = Val'Size); + + subtype Bit_Size is Natural; -- Size in bits of a bit field + subtype Small_Size is Bit_Size range 0 .. Val'Size; + -- Size of a small one + subtype Bit_Offset is Small_Size range 0 .. Val'Size - 1; + -- Starting offset + subtype Bit_Offset_In_Byte is Bit_Offset range 0 .. Storage_Unit - 1; + + procedure Copy_Bitfield + (Src_Address : Address; + Src_Offset : Bit_Offset_In_Byte; + Dest_Address : Address; + Dest_Offset : Bit_Offset_In_Byte; + Size : Bit_Size); + -- An Address and a Bit_Offset together form a "bit address". This + -- copies the source bit field to the destination. Size is the size in + -- bits of the bit field. The bit fields can be arbitrarily large, but + -- the starting offsets must be within the first byte that the Addresses + -- point to. The Address values need not be aligned. + -- + -- For example, a slice assignment of a packed bit field: + -- + -- D (D_First .. D_Last) := S (S_First .. S_Last); + -- + -- can be implemented using: + -- + -- Copy_Bitfield + -- (S (S_First)'Address, S (S_First)'Bit, + -- D (D_First)'Address, D (D_First)'Bit, + -- Size); + + end G; + +end System.Bitfield_Utils; |