]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/ada/libgnat/s-bituti.ads
[Ada] Bump copyright year
[thirdparty/gcc.git] / gcc / ada / libgnat / s-bituti.ads
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- S Y S T E M . B I T F I E L D _ U T I L S --
6 -- --
7 -- S p e c --
8 -- --
9 -- Copyright (C) 2019-2020, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
17 -- --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
21 -- --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
30 ------------------------------------------------------------------------------
31
32 package System.Bitfield_Utils is
33
34 -- This package provides a procedure for copying arbitrarily large and
35 -- arbitrarily bit-aligned bit fields.
36
37 -- Type Val is used to represent small bit fields. Val_2 represents a
38 -- contiguous pair of Vals. Val_2'Alignment is half of its size in bytes,
39 -- which is likely not the natural alignment. This is done to ensure that
40 -- any bit field that fits in a Val can fit in an aligned Val_2, starting
41 -- somewhere in the first half, and possibly crossing over into the second
42 -- half. This allows us to isolate a Val value by shifting and masking the
43 -- Val_2.
44 --
45 -- Val can be 8, 16, or 32 bits; larger values are more efficient. It can't
46 -- be 64 bits, because we need Val_2 to be a double-wide shiftable type,
47 -- and 128 bits is not supported. Instantiating with an 8-bit Val is useful
48 -- for testing and debugging; 32 bits should be used for production.
49 --
50 -- We use modular types here, not because we want modular arithmetic, but
51 -- so we can do shifting and masking. The actual for Val_2 should have
52 -- pragma Provide_Shift_Operators, so that the Shift_Left and Shift_Right
53 -- intrinsics can be passed in. It is impossible to put that pragma on a
54 -- generic formal, or on a type derived from a generic formal, so they have
55 -- to be passed in.
56 --
57 -- Endian indicates whether we're on little-endian or big-endian machine.
58
59 pragma Elaborate_Body;
60
61 Little : constant Bit_Order := Low_Order_First;
62 Big : constant Bit_Order := High_Order_First;
63
64 generic
65 type Val is mod <>;
66 type Val_2 is mod <>;
67
68 with function Shift_Left
69 (Value : Val_2;
70 Amount : Natural) return Val_2 is <>;
71
72 with function Shift_Right
73 (Value : Val_2;
74 Amount : Natural) return Val_2 is <>;
75
76 Endian : Bit_Order := Default_Bit_Order;
77
78 package G is
79 -- Assert that Val has one of the allowed sizes, and that Val_2 is twice
80 -- that.
81
82 pragma Assert (Val'Size in 8 | 16 | 32);
83 pragma Assert (Val_2'Size = Val'Size * 2);
84
85 -- Assert that both are aligned the same, to the size in bytes of Val
86 -- (not Val_2).
87
88 pragma Assert (Val'Alignment = Val'Size / Storage_Unit);
89 pragma Assert (Val_2'Alignment = Val'Alignment);
90
91 type Val_Array is array (Positive range <>) of Val;
92
93 -- It might make more sense to have:
94 -- subtype Val is Val_2 range 0 .. 2**Val'Size - 1;
95 -- But then GNAT gets the component size of Val_Array wrong.
96
97 pragma Assert (Val_Array'Alignment = Val'Alignment);
98 pragma Assert (Val_Array'Component_Size = Val'Size);
99
100 subtype Bit_Size is Natural; -- Size in bits of a bit field
101 subtype Small_Size is Bit_Size range 0 .. Val'Size;
102 -- Size of a small one
103 subtype Bit_Offset is Small_Size range 0 .. Val'Size - 1;
104 -- Starting offset
105 subtype Bit_Offset_In_Byte is Bit_Offset range 0 .. Storage_Unit - 1;
106
107 procedure Copy_Bitfield
108 (Src_Address : Address;
109 Src_Offset : Bit_Offset_In_Byte;
110 Dest_Address : Address;
111 Dest_Offset : Bit_Offset_In_Byte;
112 Size : Bit_Size);
113 -- An Address and a Bit_Offset together form a "bit address". This
114 -- copies the source bit field to the destination. Size is the size in
115 -- bits of the bit field. The bit fields can be arbitrarily large, but
116 -- the starting offsets must be within the first byte that the Addresses
117 -- point to. The Address values need not be aligned.
118 --
119 -- For example, a slice assignment of a packed bit field:
120 --
121 -- D (D_First .. D_Last) := S (S_First .. S_Last);
122 --
123 -- can be implemented using:
124 --
125 -- Copy_Bitfield
126 -- (S (S_First)'Address, S (S_First)'Bit,
127 -- D (D_First)'Address, D (D_First)'Bit,
128 -- Size);
129
130 end G;
131
132 end System.Bitfield_Utils;