--- gcc/ada/exp_ch5.adb +++ gcc/ada/exp_ch5.adb @@ -1451,20 +1451,35 @@ package body Exp_Ch5 is begin -- Determine whether Copy_Bitfield is appropriate (will work, and will -- be more efficient than component-by-component copy). Copy_Bitfield - -- doesn't work for reversed storage orders. It is efficient only for - -- slices of bit-packed arrays. - - -- Note that Expand_Assign_Array_Bitfield is disabled for now - - if False -- ??? + -- doesn't work for reversed storage orders. It is efficient for slices + -- of bit-packed arrays. Copy_Bitfield can read and write bits that are + -- not part of the objects being copied, so we don't want to use it if + -- there are volatile or independent components. If the Prefix of the + -- slice is a selected component (etc, see below), then it might be a + -- component of an object with some other volatile or independent + -- components, so we disable the optimization in that case as well. + -- We could complicate this code by actually looking for such volatile + -- and independent components. + + -- Note that Expand_Assign_Array_Bitfield is disabled for now. + + if False and then -- ??? + RTE_Available (RE_Copy_Bitfield) and then Is_Bit_Packed_Array (L_Type) and then Is_Bit_Packed_Array (R_Type) - and then RTE_Available (RE_Copy_Bitfield) and then not Reverse_Storage_Order (L_Type) and then not Reverse_Storage_Order (R_Type) and then Ndim = 1 and then not Rev and then Slices + and then not Has_Volatile_Component (L_Type) + and then not Has_Volatile_Component (R_Type) + and then not Has_Independent_Components (L_Type) + and then not Has_Independent_Components (R_Type) + and then not Nkind_In (Prefix (Name (N)), + N_Selected_Component, + N_Indexed_Component, + N_Slice) then return Expand_Assign_Array_Bitfield (N, Larray, Rarray, L_Type, R_Type, Rev); --- gcc/ada/libgnat/s-bituti.adb +++ gcc/ada/libgnat/s-bituti.adb @@ -71,6 +71,29 @@ package body System.Bitfield_Utils is -- set to Src_Value. Src_Value must have high order bits (Size and -- above) zero. The result is returned as the function result. + procedure Copy_Small_Bitfield + (Src_Address : Address; + Src_Offset : Bit_Offset; + Dest_Address : Address; + Dest_Offset : Bit_Offset; + Size : Small_Size); + -- Copy_Bitfield in the case where Size <= Val'Size. + -- The Address values must be aligned as for Val and Val_2. + -- This works for overlapping bit fields. + + procedure Copy_Large_Bitfield + (Src_Address : Address; + Src_Offset : Bit_Offset; + Dest_Address : Address; + Dest_Offset : Bit_Offset; + Size : Bit_Size); + -- Copy_Bitfield in the case where Size > Val'Size. + -- The Address values must be aligned as for Val and Val_2. + -- This works for overlapping bit fields only if the source + -- bit address is greater than or equal to the destination + -- bit address, because it copies forward (from lower to higher + -- bit addresses). + function Get_Bitfield (Src : Val_2; Src_Offset : Bit_Offset; Size : Small_Size) return Val @@ -120,29 +143,6 @@ package body System.Bitfield_Utils is Src_Offset : Bit_Offset; Dest_Address : Address; Dest_Offset : Bit_Offset; - Size : Small_Size); - -- Copy_Bitfield in the case where Size <= Val'Size. - -- The Address values must be aligned as for Val and Val_2. - -- This works for overlapping bit fields. - - procedure Copy_Large_Bitfield - (Src_Address : Address; - Src_Offset : Bit_Offset; - Dest_Address : Address; - Dest_Offset : Bit_Offset; - Size : Bit_Size); - -- Copy_Bitfield in the case where Size > Val'Size. - -- The Address values must be aligned as for Val and Val_2. - -- This works for overlapping bit fields only if the source - -- bit address is greater than or equal to the destination - -- bit address, because it copies forward (from lower to higher - -- bit addresses). - - procedure Copy_Small_Bitfield - (Src_Address : Address; - Src_Offset : Bit_Offset; - Dest_Address : Address; - Dest_Offset : Bit_Offset; Size : Small_Size) is Src : constant Val_2 with Import, Address => Src_Address;