R_Type := Get_Actual_Subtype (Act_Rhs);
Loop_Required := True;
- -- We require a loop if the left side is possibly bit unaligned
+ -- We require a loop if either side is possibly bit aligned
elsif Possible_Bit_Aligned_Component (Lhs)
or else
return;
-- If either operand is bit packed, then we need a loop, since we can't
- -- be sure that the slice is byte aligned. Similarly, if either operand
- -- is a possibly unaligned slice, then we need a loop (since the back
- -- end cannot handle unaligned slices).
+ -- be sure that the slice is byte aligned.
elsif Is_Bit_Packed_Array (L_Type)
or else Is_Bit_Packed_Array (R_Type)
- or else Is_Possibly_Unaligned_Slice (Lhs)
- or else Is_Possibly_Unaligned_Slice (Rhs)
then
Loop_Required := True;
-- Component_May_Be_Bit_Aligned --
----------------------------------
- function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
+ function Component_May_Be_Bit_Aligned
+ (Comp : Entity_Id;
+ For_Slice : Boolean := False) return Boolean
+ is
UT : Entity_Id;
begin
-- If we know that we have a small (at most the maximum integer size)
-- record or bit-packed array, then everything is fine, since the back
- -- end can handle these cases correctly.
+ -- end can handle these cases correctly, except if a slice is involved.
elsif Known_Esize (Comp)
and then Esize (Comp) <= System_Max_Integer_Size
and then (Is_Record_Type (UT) or else Is_Bit_Packed_Array (UT))
+ and then not For_Slice
then
return False;
-- Possible_Bit_Aligned_Component --
------------------------------------
- function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
+ function Possible_Bit_Aligned_Component
+ (N : Node_Id;
+ For_Slice : Boolean := False) return Boolean
+ is
begin
-- Do not process an unanalyzed node because it is not yet decorated and
-- most checks performed below will fail.
-- indexing from a possibly unaligned component.
else
- return Possible_Bit_Aligned_Component (P);
+ return Possible_Bit_Aligned_Component (P, For_Slice);
end if;
end;
-- This is the crucial test: if the component itself causes
-- trouble, then we can stop and return True.
- if Component_May_Be_Bit_Aligned (Comp) then
+ if Component_May_Be_Bit_Aligned (Comp, For_Slice) then
return True;
-- Otherwise, we need to test the prefix, to see if we are
-- selecting from a possibly unaligned component.
else
- return Possible_Bit_Aligned_Component (P);
+ return Possible_Bit_Aligned_Component (P, For_Slice);
end if;
end;
-- then for sure the slice is.
when N_Slice =>
- return Possible_Bit_Aligned_Component (Prefix (N));
+ return Possible_Bit_Aligned_Component (Prefix (N), True);
-- For an unchecked conversion, check whether the expression may
-- be bit aligned.
when N_Unchecked_Type_Conversion =>
- return Possible_Bit_Aligned_Component (Expression (N));
+ return Possible_Bit_Aligned_Component (Expression (N), For_Slice);
-- If we have none of the above, it means that we have fallen off the
-- top testing prefixes recursively, and we now have a stand alone
-- in which case we need to look into the renamed object.
when others =>
- if Is_Entity_Name (N)
+ return Is_Entity_Name (N)
and then Is_Object (Entity (N))
and then Present (Renamed_Object (Entity (N)))
- then
- return
- Possible_Bit_Aligned_Component (Renamed_Object (Entity (N)));
- else
- return False;
- end if;
+ and then Possible_Bit_Aligned_Component
+ (Renamed_Object (Entity (N)), For_Slice);
end case;
end Possible_Bit_Aligned_Component;
-- since for floating-point, abs, unary "-", and unary "+" can never
-- case overflow.
- function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean;
+ function Component_May_Be_Bit_Aligned
+ (Comp : Entity_Id;
+ For_Slice : Boolean := False) return Boolean;
-- This function is in charge of detecting record components that may cause
- -- trouble for the back end if an attempt is made to access the component
- -- as a whole. The back end can handle such accesses with no problem if the
- -- components involved are small (64 bits or less) records or scalar items
+ -- trouble for the back end if an attempt is made to access the component,
+ -- either as a whole if For_Slice is False, or through an array slice if
+ -- For_Slice is True. The back end can handle such accesses only if the
+ -- components involved are small (64/128 bits or less) records or scalars
-- (including bit-packed arrays represented with a modular type), or else
-- if they are aligned on byte boundaries (i.e. starting on a byte boundary
-- and occupying an integral number of bytes).
--
- -- However, problems arise for records larger than 64 bits, or for arrays
+ -- However problems arise for records larger than 64/128 bits or for arrays
-- (other than bit-packed arrays represented with a modular type) if the
-- component either does not start on a byte boundary or does not occupy an
-- integral number of bytes (i.e. there are some bits possibly shared with
-- address might be captured in a way we do not detect. A value of True is
-- returned only if the replacement is safe.
- function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean;
+ function Possible_Bit_Aligned_Component
+ (N : Node_Id;
+ For_Slice : Boolean := False) return Boolean;
-- This function is used during processing the assignment of a record or an
-- array, or the construction of an aggregate. The argument N is either the
-- left or the right hand side of an assignment and the function determines