This change ensures proper processing for a packed array of 4-bit records
specified with reverse scalar storage order.
The following program must compile quietly and execute as shown:
$ gnatmake -q reduced_pkd_array_small_rec
$ ./reduced_pkd_array_small_rec
Config 0 = 1
Config 1 = 3
Config 2 = 5
Config 3 = 7
Bit pattern: 19 87
with Ada.Text_Io; use Ada.Text_IO;
with System.Storage_Elements; use System.Storage_Elements;
procedure reduced_pkd_array_small_rec is
type Int3 is range 0 .. 7;
for Int3'Size use 3;
type Small_Rec is record
B : Boolean := False;
I : Int3 := 0;
end record;
pragma pack (Small_Rec);
for Small_Rec'Size use 4;
for Small_Rec'Bit_Order use System.High_Order_First;
for Small_Rec'Scalar_Storage_Order use System.High_Order_First;
for Small_Rec use record
B at 0 range 0 .. 0;
I at 0 range 1 .. 3;
end record;
type Pakd_Array is array (Integer range 0 .. 3) of Small_Rec;
pragma pack (Pakd_Array);
for Pakd_Array'Scalar_Storage_Order use System.High_Order_First;
Config : Pakd_Array;
SA : Storage_Array (1 .. Config'Size / 8);
for SA'Address use Config'Address;
pragma Import (Ada, SA);
begin
Config(0).I := 1;
Config(1).I := 3;
Config(2).I := 5;
Config(3).I := 7;
Put_Line ("Config 0 = " & Config(0).I'Img);
Put_Line ("Config 1 = " & Config(1).I'Img);
Put_Line ("Config 2 = " & Config(2).I'Img);
Put_Line ("Config 3 = " & Config(3).I'Img);
Put ("Bit pattern:");
for J in SA'Range loop
Put (" " & SA (J)'Img);
end loop;
New_Line;
end;
Tested on x86_64-pc-linux-gnu, committed on trunk
2014-05-21 Thomas Quinot <[email protected]>
* exp_pakd.adb (Byte_Swap): Handle the case of a sub-byte
component. No byte swapping occurs, but this procedure also takes
care of appropriately justifying the argument.
Index: exp_pakd.adb
===================================================================
--- exp_pakd.adb (revision 210703)
+++ exp_pakd.adb (working copy)
@@ -576,20 +576,26 @@
Shift : Uint;
begin
- pragma Assert (T_Size > 8);
+ if T_Size <= 8 then
+ Swap_F := Empty;
+ Swap_T := RTE (RE_Unsigned_8);
- if T_Size <= 16 then
- Swap_RE := RE_Bswap_16;
+ else
+ if T_Size <= 16 then
+ Swap_RE := RE_Bswap_16;
- elsif T_Size <= 32 then
- Swap_RE := RE_Bswap_32;
+ elsif T_Size <= 32 then
+ Swap_RE := RE_Bswap_32;
- else pragma Assert (T_Size <= 64);
- Swap_RE := RE_Bswap_64;
+ else pragma Assert (T_Size <= 64);
+ Swap_RE := RE_Bswap_64;
+ end if;
+
+ Swap_F := RTE (Swap_RE);
+ Swap_T := Etype (Swap_F);
+
end if;
- Swap_F := RTE (Swap_RE);
- Swap_T := Etype (Swap_F);
Shift := Esize (Swap_T) - T_Size;
Arg := RJ_Unchecked_Convert_To (Swap_T, N);
@@ -601,10 +607,14 @@
Right_Opnd => Make_Integer_Literal (Loc, Shift));
end if;
- Swapped :=
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Swap_F, Loc),
- Parameter_Associations => New_List (Arg));
+ if Present (Swap_F) then
+ Swapped :=
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (Swap_F, Loc),
+ Parameter_Associations => New_List (Arg));
+ else
+ Swapped := Arg;
+ end if;
if Right_Justify and then Shift > Uint_0 then
Swapped :=