-- For big-endian machines, element zero is at the left hand end
-- (high order end) of a bit field.
- -- The shifts that are used to right justify a field therefore differ
- -- in the two cases. For the little-endian case, we can simply use the
- -- bit number (i.e. the element number * element size) as the count for
- -- a right shift. For the big-endian case, we have to subtract the shift
- -- count from an appropriate constant to use in the right shift. We use
- -- rotates instead of shifts (which is necessary in the store case to
- -- preserve other fields), and we expect that the backend will be able
- -- to change the right rotate into a left rotate, avoiding the subtract,
- -- if the architecture provides such an instruction.
+ -- The shifts that are used to right justify a field therefore differ in
+ -- the two cases. For the little-endian case, we can simply use the bit
+ -- number (i.e. the element number * element size) as the count for a right
+ -- shift. For the big-endian case, we have to subtract the shift count from
+ -- an appropriate constant to use in the right shift. We use rotates
+ -- instead of shifts (which is necessary in the store case to preserve
+ -- other fields), and we expect that the backend will be able to change the
+ -- right rotate into a left rotate, avoiding the subtract, if the machine
+ -- architecture provides such an instruction.
----------------------------------------------
-- Entity Tables for Packed Access Routines --
----------------------------------------------
- -- For the cases of component size = 3,5-7,9-15,17-31,33-63 we call
- -- library routines. This table is used to obtain the entity for the
- -- proper routine.
+ -- For the cases of component size = 3,5-7,9-15,17-31,33-63 we call library
+ -- routines. This table provides the entity for the proper routine.
type E_Array is array (Int range 01 .. 63) of RE_Id;
62 => RE_Bits_62,
63 => RE_Bits_63);
- -- Array of Get routine entities. These are used to obtain an element
- -- from a packed array. The N'th entry is used to obtain elements from
- -- a packed array whose component size is N. RE_Null is used as a null
- -- entry, for the cases where a library routine is not used.
+ -- Array of Get routine entities. These are used to obtain an element from
+ -- a packed array. The N'th entry is used to obtain elements from a packed
+ -- array whose component size is N. RE_Null is used as a null entry, for
+ -- the cases where a library routine is not used.
Get_Id : constant E_Array :=
(01 => RE_Null,
63 => RE_Get_63);
-- Array of Get routine entities to be used in the case where the packed
- -- array is itself a component of a packed structure, and therefore may
- -- not be fully aligned. This only affects the even sizes, since for the
- -- odd sizes, we do not get any fixed alignment in any case.
+ -- array is itself a component of a packed structure, and therefore may not
+ -- be fully aligned. This only affects the even sizes, since for the odd
+ -- sizes, we do not get any fixed alignment in any case.
GetU_Id : constant E_Array :=
(01 => RE_Null,
62 => RE_GetU_62,
63 => RE_Get_63);
- -- Array of Set routine entities. These are used to assign an element
- -- of a packed array. The N'th entry is used to assign elements for
- -- a packed array whose component size is N. RE_Null is used as a null
- -- entry, for the cases where a library routine is not used.
+ -- Array of Set routine entities. These are used to assign an element of a
+ -- packed array. The N'th entry is used to assign elements for a packed
+ -- array whose component size is N. RE_Null is used as a null entry, for
+ -- the cases where a library routine is not used.
Set_Id : constant E_Array :=
(01 => RE_Null,
63 => RE_Set_63);
-- Array of Set routine entities to be used in the case where the packed
- -- array is itself a component of a packed structure, and therefore may
- -- not be fully aligned. This only affects the even sizes, since for the
- -- odd sizes, we do not get any fixed alignment in any case.
+ -- array is itself a component of a packed structure, and therefore may not
+ -- be fully aligned. This only affects the even sizes, since for the odd
+ -- sizes, we do not get any fixed alignment in any case.
SetU_Id : constant E_Array :=
(01 => RE_Null,
(Atyp : Entity_Id;
N : Node_Id;
Subscr : out Node_Id);
- -- Given a constrained array type Atyp, and an indexed component node
- -- N referencing an array object of this type, build an expression of
- -- type Standard.Integer representing the zero-based linear subscript
- -- value. This expression includes any required range checks.
+ -- Given a constrained array type Atyp, and an indexed component node N
+ -- referencing an array object of this type, build an expression of type
+ -- Standard.Integer representing the zero-based linear subscript value.
+ -- This expression includes any required range checks.
procedure Convert_To_PAT_Type (Aexp : Node_Id);
-- Given an expression of a packed array type, builds a corresponding
-- The statement to be generated is:
- -- Obj := atyp!((Obj and Mask1) or (shift_left (rhs, shift)))
+ -- Obj := atyp!((Obj and Mask1) or (shift_left (rhs, Shift)))
- -- where mask1 is obtained by shifting Cmask left Shift bits
+ -- where Mask1 is obtained by shifting Cmask left Shift bits
-- and then complementing the result.
-- the "and Mask1" is omitted if rhs is constant and all 1 bits
Rhs_Val_Known := False;
end if;
- -- Some special checks for the case where the right hand value
- -- is known at compile time. Basically we have to take care of
- -- the implicit conversion to the subtype of the component object.
+ -- Some special checks for the case where the right hand value is
+ -- known at compile time. Basically we have to take care of the
+ -- implicit conversion to the subtype of the component object.
if Rhs_Val_Known then
- -- If we have a biased component type then we must manually do
- -- the biasing, since we are taking responsibility in this case
- -- for constructing the exact bit pattern to be used.
+ -- If we have a biased component type then we must manually do the
+ -- biasing, since we are taking responsibility in this case for
+ -- constructing the exact bit pattern to be used.
if Has_Biased_Representation (Ctyp) then
Rhs_Val := Rhs_Val - Expr_Rep_Value (Type_Low_Bound (Ctyp));
end if;
- -- For a negative value, we manually convert the twos complement
+ -- For a negative value, we manually convert the two's complement
-- value to a corresponding unsigned value, so that the proper
-- field width is maintained. If we did not do this, we would
-- get too many leading sign bits later on.
Rhs := Unchecked_Convert_To (RTE (Bits_Id (Csiz)), Rhs);
end if;
- -- Set Etype, since it can be referenced before the
- -- node is completely analyzed.
+ -- Set Etype, since it can be referenced before the node is
+ -- completely analyzed.
Set_Etype (Rhs, Etyp);
Set_Parent (Arg, Parent (N));
Analyze_And_Resolve (Arg);
- Rewrite (N,
- RJ_Unchecked_Convert_To (Ctyp, Arg));
+ Rewrite (N, RJ_Unchecked_Convert_To (Ctyp, Arg));
-- All other component sizes for non-modular case
Convert_To_PAT_Type (Opnd);
PAT := Etype (Opnd);
- -- For the case where the packed array type is a modular type,
- -- not A expands simply into:
+ -- For the case where the packed array type is a modular type, "not A"
+ -- expands simply into:
- -- rtyp!(PAT!(A) xor mask)
+ -- Rtyp!(PAT!(A) xor Mask)
- -- where PAT is the packed array type, and mask is a mask of all
- -- one bits of length equal to the size of this packed type and
- -- rtyp is the actual subtype of the operand
+ -- where PAT is the packed array type, Mask is a mask of all 1 bits of
+ -- length equal to the size of this packed type, and Rtyp is the actual
+ -- actual subtype of the operand.
Lit := Make_Integer_Literal (Loc, 2 ** RM_Size (PAT) - 1);
Set_Print_In_Hex (Lit);
-- System.Bit_Ops.Bit_Not
-- (Opnd'Address,
- -- Typ'Length * Typ'Component_Size;
+ -- Typ'Length * Typ'Component_Size,
-- Result'Address);
- -- where Opnd is the Packed_Bytes{1,2,4} operand and the second
- -- argument is the length of the operand in bits. Then we replace
- -- the expression by a reference to Result.
+ -- where Opnd is the Packed_Bytes{1,2,4} operand and the second argument
+ -- is the length of the operand in bits. We then replace the expression
+ -- with a reference to Result.
else
declare
begin
Insert_Actions (N, New_List (
-
Make_Object_Declaration (Loc,
Defining_Identifier => Result_Ent,
- Object_Definition => New_Occurrence_Of (Rtyp, Loc)),
+ Object_Definition => New_Occurrence_Of (Rtyp, Loc)),
Make_Procedure_Call_Statement (Loc,
Name => New_Occurrence_Of (RTE (RE_Bit_Not), Loc),
Parameter_Associations => New_List (
-
Make_Byte_Aligned_Attribute_Reference (Loc,
Prefix => Opnd,
Attribute_Name => Name_Address),
Make_Integer_Literal (Loc, Component_Size (Rtyp))),
Make_Byte_Aligned_Attribute_Reference (Loc,
- Prefix => New_Occurrence_Of (Result_Ent, Loc),
+ Prefix => New_Occurrence_Of (Result_Ent, Loc),
Attribute_Name => Name_Address)))));
- Rewrite (N,
- New_Occurrence_Of (Result_Ent, Loc));
+ Rewrite (N, New_Occurrence_Of (Result_Ent, Loc));
end;
end if;
Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
-
end Expand_Packed_Not;
-----------------------------
Source_Siz := UI_To_Int (RM_Size (Source_Typ));
Target_Siz := UI_To_Int (RM_Size (Target_Typ));
- -- First step, if the source type is not a discrete type, then we
- -- first convert to a modular type of the source length, since
- -- otherwise, on a big-endian machine, we get left-justification.
- -- We do it for little-endian machines as well, because there might
- -- be junk bits that are not cleared if the type is not numeric.
+ -- First step, if the source type is not a discrete type, then we first
+ -- convert to a modular type of the source length, since otherwise, on
+ -- a big-endian machine, we get left-justification. We do it for little-
+ -- endian machines as well, because there might be junk bits that are
+ -- not cleared if the type is not numeric.
if Source_Siz /= Target_Siz
- and then not Is_Discrete_Type (Source_Typ)
+ and then not Is_Discrete_Type (Source_Typ)
then
Src := Unchecked_Convert_To (RTE (Bits_Id (Source_Siz)), Src);
end if;
- -- In the big endian case, if the lengths of the two types differ,
- -- then we must worry about possible left justification in the
- -- conversion, and avoiding that is what this is all about.
+ -- In the big endian case, if the lengths of the two types differ, then
+ -- we must worry about possible left justification in the conversion,
+ -- and avoiding that is what this is all about.
if Bytes_Big_Endian and then Source_Siz /= Target_Siz then
-- Next step. If the target is not a discrete type, then we first
- -- convert to a modular type of the target length, since
- -- otherwise, on a big-endian machine, we get left-justification.
+ -- convert to a modular type of the target length, since otherwise,
+ -- on a big-endian machine, we get left-justification.
if not Is_Discrete_Type (Target_Typ) then
Src := Unchecked_Convert_To (RTE (Bits_Id (Target_Siz)), Src);
-- Setup_Enumeration_Packed_Array_Reference --
----------------------------------------------
- -- All we have to do here is to find the subscripts that correspond
- -- to the index positions that have non-standard enumeration types
- -- and insert a Pos attribute to get the proper subscript value.
+ -- All we have to do here is to find the subscripts that correspond to the
+ -- index positions that have non-standard enumeration types and insert a
+ -- Pos attribute to get the proper subscript value.
- -- Finally the prefix must be uncheck converted to the corresponding
- -- packed array type.
+ -- Finally the prefix must be uncheck-converted to the corresponding packed
+ -- array type.
- -- Note that the component type is unchanged, so we do not need to
- -- fiddle with the types (Gigi always automatically takes the packed
- -- array type if it is set, as it will be in this case).
+ -- Note that the component type is unchanged, so we do not need to fiddle
+ -- with the types (Gigi always automatically takes the packed array type if
+ -- it is set, as it will be in this case).
procedure Setup_Enumeration_Packed_Array_Reference (N : Node_Id) is
Pfx : constant Node_Id := Prefix (N);
Expr : Node_Id;
begin
- -- If the array is unconstrained, then we replace the array
- -- reference with its actual subtype. This actual subtype will
- -- have a packed array type with appropriate bounds.
+ -- If the array is unconstrained, then we replace the array reference
+ -- with its actual subtype. This actual subtype will have a packed array
+ -- type with appropriate bounds.
if not Is_Constrained (Packed_Array_Type (Etype (Pfx))) then
Convert_To_Actual_Subtype (Pfx);
Expressions => Exprs));
Analyze_And_Resolve (N, Typ);
-
end Setup_Enumeration_Packed_Array_Reference;
-----------------------------------------
Compute_Linear_Subscript (Atyp, N, Shift);
- -- If the component size is not 1, then the subscript must be
- -- multiplied by the component size to get the shift count.
+ -- If the component size is not 1, then the subscript must be multiplied
+ -- by the component size to get the shift count.
if Csiz /= 1 then
Shift :=
Right_Opnd => Shift);
end if;
- -- If we have the array case, then this shift count must be broken
- -- down into a byte subscript, and a shift within the byte.
+ -- If we have the array case, then this shift count must be broken down
+ -- into a byte subscript, and a shift within the byte.
if Is_Array_Type (PAT) then
Shift := New_Shift;
end;
- -- For the modular integer case, the object to be manipulated is
- -- the entire array, so Obj is unchanged. Note that we will reset
- -- its type to PAT before returning to the caller.
+ -- For the modular integer case, the object to be manipulated is the
+ -- entire array, so Obj is unchanged. Note that we will reset its type
+ -- to PAT before returning to the caller.
else
null;
-- Here we have the case of 2-bit fields
- -- For the little-endian case, we already have the proper shift
- -- count set, e.g. for element 2, the shift count is 2*2 = 4.
+ -- For the little-endian case, we already have the proper shift count
+ -- set, e.g. for element 2, the shift count is 2*2 = 4.
- -- For the big endian case, we have to adjust the shift count,
- -- computing it as (N - F) - shift, where N is the number of bits
- -- in an element of the array used to implement the packed array,
- -- F is the number of bits in a source level array element, and
- -- shift is the count so far computed.
+ -- For the big endian case, we have to adjust the shift count, computing
+ -- it as (N - F) - Shift, where N is the number of bits in an element of
+ -- the array used to implement the packed array, F is the number of bits
+ -- in a source array element, and Shift is the count so far computed.
if Bytes_Big_Endian then
Shift :=