1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT COMPILER COMPONENTS                         --
4--                                                                          --
5--                             E X P _ P A K D                              --
6--                                                                          --
7--                                 B o d y                                  --
8--                                                                          --
9--          Copyright (C) 1992-2012, 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.  See the GNU General Public License --
17-- for  more details.  You should have  received  a copy of the GNU General --
18-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19-- http://www.gnu.org/licenses for a complete copy of the license.          --
20--                                                                          --
21-- GNAT was originally developed  by the GNAT team at  New York University. --
22-- Extensive contributions were provided by Ada Core Technologies Inc.      --
23--                                                                          --
24------------------------------------------------------------------------------
25
26with Atree;    use Atree;
27with Checks;   use Checks;
28with Einfo;    use Einfo;
29with Errout;   use Errout;
30with Exp_Dbug; use Exp_Dbug;
31with Exp_Util; use Exp_Util;
32with Layout;   use Layout;
33with Namet;    use Namet;
34with Nlists;   use Nlists;
35with Nmake;    use Nmake;
36with Opt;      use Opt;
37with Rtsfind;  use Rtsfind;
38with Sem;      use Sem;
39with Sem_Aux;  use Sem_Aux;
40with Sem_Ch3;  use Sem_Ch3;
41with Sem_Ch8;  use Sem_Ch8;
42with Sem_Ch13; use Sem_Ch13;
43with Sem_Eval; use Sem_Eval;
44with Sem_Res;  use Sem_Res;
45with Sem_Util; use Sem_Util;
46with Sinfo;    use Sinfo;
47with Snames;   use Snames;
48with Stand;    use Stand;
49with Targparm; use Targparm;
50with Tbuild;   use Tbuild;
51with Ttypes;   use Ttypes;
52with Uintp;    use Uintp;
53
54package body Exp_Pakd is
55
56   ---------------------------
57   -- Endian Considerations --
58   ---------------------------
59
60   --  As described in the specification, bit numbering in a packed array
61   --  is consistent with bit numbering in a record representation clause,
62   --  and hence dependent on the endianness of the machine:
63
64   --    For little-endian machines, element zero is at the right hand end
65   --    (low order end) of a bit field.
66
67   --    For big-endian machines, element zero is at the left hand end
68   --    (high order end) of a bit field.
69
70   --  The shifts that are used to right justify a field therefore differ in
71   --  the two cases. For the little-endian case, we can simply use the bit
72   --  number (i.e. the element number * element size) as the count for a right
73   --  shift. For the big-endian case, we have to subtract the shift count from
74   --  an appropriate constant to use in the right shift. We use rotates
75   --  instead of shifts (which is necessary in the store case to preserve
76   --  other fields), and we expect that the backend will be able to change the
77   --  right rotate into a left rotate, avoiding the subtract, if the machine
78   --  architecture provides such an instruction.
79
80   ----------------------------------------------
81   -- Entity Tables for Packed Access Routines --
82   ----------------------------------------------
83
84   --  For the cases of component size = 3,5-7,9-15,17-31,33-63 we call library
85   --  routines. This table provides the entity for the proper routine.
86
87   type E_Array is array (Int range 01 .. 63) of RE_Id;
88
89   --  Array of Bits_nn entities. Note that we do not use library routines
90   --  for the 8-bit and 16-bit cases, but we still fill in the table, using
91   --  entries from System.Unsigned, because we also use this table for
92   --  certain special unchecked conversions in the big-endian case.
93
94   Bits_Id : constant E_Array :=
95     (01 => RE_Bits_1,
96      02 => RE_Bits_2,
97      03 => RE_Bits_03,
98      04 => RE_Bits_4,
99      05 => RE_Bits_05,
100      06 => RE_Bits_06,
101      07 => RE_Bits_07,
102      08 => RE_Unsigned_8,
103      09 => RE_Bits_09,
104      10 => RE_Bits_10,
105      11 => RE_Bits_11,
106      12 => RE_Bits_12,
107      13 => RE_Bits_13,
108      14 => RE_Bits_14,
109      15 => RE_Bits_15,
110      16 => RE_Unsigned_16,
111      17 => RE_Bits_17,
112      18 => RE_Bits_18,
113      19 => RE_Bits_19,
114      20 => RE_Bits_20,
115      21 => RE_Bits_21,
116      22 => RE_Bits_22,
117      23 => RE_Bits_23,
118      24 => RE_Bits_24,
119      25 => RE_Bits_25,
120      26 => RE_Bits_26,
121      27 => RE_Bits_27,
122      28 => RE_Bits_28,
123      29 => RE_Bits_29,
124      30 => RE_Bits_30,
125      31 => RE_Bits_31,
126      32 => RE_Unsigned_32,
127      33 => RE_Bits_33,
128      34 => RE_Bits_34,
129      35 => RE_Bits_35,
130      36 => RE_Bits_36,
131      37 => RE_Bits_37,
132      38 => RE_Bits_38,
133      39 => RE_Bits_39,
134      40 => RE_Bits_40,
135      41 => RE_Bits_41,
136      42 => RE_Bits_42,
137      43 => RE_Bits_43,
138      44 => RE_Bits_44,
139      45 => RE_Bits_45,
140      46 => RE_Bits_46,
141      47 => RE_Bits_47,
142      48 => RE_Bits_48,
143      49 => RE_Bits_49,
144      50 => RE_Bits_50,
145      51 => RE_Bits_51,
146      52 => RE_Bits_52,
147      53 => RE_Bits_53,
148      54 => RE_Bits_54,
149      55 => RE_Bits_55,
150      56 => RE_Bits_56,
151      57 => RE_Bits_57,
152      58 => RE_Bits_58,
153      59 => RE_Bits_59,
154      60 => RE_Bits_60,
155      61 => RE_Bits_61,
156      62 => RE_Bits_62,
157      63 => RE_Bits_63);
158
159   --  Array of Get routine entities. These are used to obtain an element from
160   --  a packed array. The N'th entry is used to obtain elements from a packed
161   --  array whose component size is N. RE_Null is used as a null entry, for
162   --  the cases where a library routine is not used.
163
164   Get_Id : constant E_Array :=
165     (01 => RE_Null,
166      02 => RE_Null,
167      03 => RE_Get_03,
168      04 => RE_Null,
169      05 => RE_Get_05,
170      06 => RE_Get_06,
171      07 => RE_Get_07,
172      08 => RE_Null,
173      09 => RE_Get_09,
174      10 => RE_Get_10,
175      11 => RE_Get_11,
176      12 => RE_Get_12,
177      13 => RE_Get_13,
178      14 => RE_Get_14,
179      15 => RE_Get_15,
180      16 => RE_Null,
181      17 => RE_Get_17,
182      18 => RE_Get_18,
183      19 => RE_Get_19,
184      20 => RE_Get_20,
185      21 => RE_Get_21,
186      22 => RE_Get_22,
187      23 => RE_Get_23,
188      24 => RE_Get_24,
189      25 => RE_Get_25,
190      26 => RE_Get_26,
191      27 => RE_Get_27,
192      28 => RE_Get_28,
193      29 => RE_Get_29,
194      30 => RE_Get_30,
195      31 => RE_Get_31,
196      32 => RE_Null,
197      33 => RE_Get_33,
198      34 => RE_Get_34,
199      35 => RE_Get_35,
200      36 => RE_Get_36,
201      37 => RE_Get_37,
202      38 => RE_Get_38,
203      39 => RE_Get_39,
204      40 => RE_Get_40,
205      41 => RE_Get_41,
206      42 => RE_Get_42,
207      43 => RE_Get_43,
208      44 => RE_Get_44,
209      45 => RE_Get_45,
210      46 => RE_Get_46,
211      47 => RE_Get_47,
212      48 => RE_Get_48,
213      49 => RE_Get_49,
214      50 => RE_Get_50,
215      51 => RE_Get_51,
216      52 => RE_Get_52,
217      53 => RE_Get_53,
218      54 => RE_Get_54,
219      55 => RE_Get_55,
220      56 => RE_Get_56,
221      57 => RE_Get_57,
222      58 => RE_Get_58,
223      59 => RE_Get_59,
224      60 => RE_Get_60,
225      61 => RE_Get_61,
226      62 => RE_Get_62,
227      63 => RE_Get_63);
228
229   --  Array of Get routine entities to be used in the case where the packed
230   --  array is itself a component of a packed structure, and therefore may not
231   --  be fully aligned. This only affects the even sizes, since for the odd
232   --  sizes, we do not get any fixed alignment in any case.
233
234   GetU_Id : constant E_Array :=
235     (01 => RE_Null,
236      02 => RE_Null,
237      03 => RE_Get_03,
238      04 => RE_Null,
239      05 => RE_Get_05,
240      06 => RE_GetU_06,
241      07 => RE_Get_07,
242      08 => RE_Null,
243      09 => RE_Get_09,
244      10 => RE_GetU_10,
245      11 => RE_Get_11,
246      12 => RE_GetU_12,
247      13 => RE_Get_13,
248      14 => RE_GetU_14,
249      15 => RE_Get_15,
250      16 => RE_Null,
251      17 => RE_Get_17,
252      18 => RE_GetU_18,
253      19 => RE_Get_19,
254      20 => RE_GetU_20,
255      21 => RE_Get_21,
256      22 => RE_GetU_22,
257      23 => RE_Get_23,
258      24 => RE_GetU_24,
259      25 => RE_Get_25,
260      26 => RE_GetU_26,
261      27 => RE_Get_27,
262      28 => RE_GetU_28,
263      29 => RE_Get_29,
264      30 => RE_GetU_30,
265      31 => RE_Get_31,
266      32 => RE_Null,
267      33 => RE_Get_33,
268      34 => RE_GetU_34,
269      35 => RE_Get_35,
270      36 => RE_GetU_36,
271      37 => RE_Get_37,
272      38 => RE_GetU_38,
273      39 => RE_Get_39,
274      40 => RE_GetU_40,
275      41 => RE_Get_41,
276      42 => RE_GetU_42,
277      43 => RE_Get_43,
278      44 => RE_GetU_44,
279      45 => RE_Get_45,
280      46 => RE_GetU_46,
281      47 => RE_Get_47,
282      48 => RE_GetU_48,
283      49 => RE_Get_49,
284      50 => RE_GetU_50,
285      51 => RE_Get_51,
286      52 => RE_GetU_52,
287      53 => RE_Get_53,
288      54 => RE_GetU_54,
289      55 => RE_Get_55,
290      56 => RE_GetU_56,
291      57 => RE_Get_57,
292      58 => RE_GetU_58,
293      59 => RE_Get_59,
294      60 => RE_GetU_60,
295      61 => RE_Get_61,
296      62 => RE_GetU_62,
297      63 => RE_Get_63);
298
299   --  Array of Set routine entities. These are used to assign an element of a
300   --  packed array. The N'th entry is used to assign elements for a packed
301   --  array whose component size is N. RE_Null is used as a null entry, for
302   --  the cases where a library routine is not used.
303
304   Set_Id : constant E_Array :=
305     (01 => RE_Null,
306      02 => RE_Null,
307      03 => RE_Set_03,
308      04 => RE_Null,
309      05 => RE_Set_05,
310      06 => RE_Set_06,
311      07 => RE_Set_07,
312      08 => RE_Null,
313      09 => RE_Set_09,
314      10 => RE_Set_10,
315      11 => RE_Set_11,
316      12 => RE_Set_12,
317      13 => RE_Set_13,
318      14 => RE_Set_14,
319      15 => RE_Set_15,
320      16 => RE_Null,
321      17 => RE_Set_17,
322      18 => RE_Set_18,
323      19 => RE_Set_19,
324      20 => RE_Set_20,
325      21 => RE_Set_21,
326      22 => RE_Set_22,
327      23 => RE_Set_23,
328      24 => RE_Set_24,
329      25 => RE_Set_25,
330      26 => RE_Set_26,
331      27 => RE_Set_27,
332      28 => RE_Set_28,
333      29 => RE_Set_29,
334      30 => RE_Set_30,
335      31 => RE_Set_31,
336      32 => RE_Null,
337      33 => RE_Set_33,
338      34 => RE_Set_34,
339      35 => RE_Set_35,
340      36 => RE_Set_36,
341      37 => RE_Set_37,
342      38 => RE_Set_38,
343      39 => RE_Set_39,
344      40 => RE_Set_40,
345      41 => RE_Set_41,
346      42 => RE_Set_42,
347      43 => RE_Set_43,
348      44 => RE_Set_44,
349      45 => RE_Set_45,
350      46 => RE_Set_46,
351      47 => RE_Set_47,
352      48 => RE_Set_48,
353      49 => RE_Set_49,
354      50 => RE_Set_50,
355      51 => RE_Set_51,
356      52 => RE_Set_52,
357      53 => RE_Set_53,
358      54 => RE_Set_54,
359      55 => RE_Set_55,
360      56 => RE_Set_56,
361      57 => RE_Set_57,
362      58 => RE_Set_58,
363      59 => RE_Set_59,
364      60 => RE_Set_60,
365      61 => RE_Set_61,
366      62 => RE_Set_62,
367      63 => RE_Set_63);
368
369   --  Array of Set routine entities to be used in the case where the packed
370   --  array is itself a component of a packed structure, and therefore may not
371   --  be fully aligned. This only affects the even sizes, since for the odd
372   --  sizes, we do not get any fixed alignment in any case.
373
374   SetU_Id : constant E_Array :=
375     (01 => RE_Null,
376      02 => RE_Null,
377      03 => RE_Set_03,
378      04 => RE_Null,
379      05 => RE_Set_05,
380      06 => RE_SetU_06,
381      07 => RE_Set_07,
382      08 => RE_Null,
383      09 => RE_Set_09,
384      10 => RE_SetU_10,
385      11 => RE_Set_11,
386      12 => RE_SetU_12,
387      13 => RE_Set_13,
388      14 => RE_SetU_14,
389      15 => RE_Set_15,
390      16 => RE_Null,
391      17 => RE_Set_17,
392      18 => RE_SetU_18,
393      19 => RE_Set_19,
394      20 => RE_SetU_20,
395      21 => RE_Set_21,
396      22 => RE_SetU_22,
397      23 => RE_Set_23,
398      24 => RE_SetU_24,
399      25 => RE_Set_25,
400      26 => RE_SetU_26,
401      27 => RE_Set_27,
402      28 => RE_SetU_28,
403      29 => RE_Set_29,
404      30 => RE_SetU_30,
405      31 => RE_Set_31,
406      32 => RE_Null,
407      33 => RE_Set_33,
408      34 => RE_SetU_34,
409      35 => RE_Set_35,
410      36 => RE_SetU_36,
411      37 => RE_Set_37,
412      38 => RE_SetU_38,
413      39 => RE_Set_39,
414      40 => RE_SetU_40,
415      41 => RE_Set_41,
416      42 => RE_SetU_42,
417      43 => RE_Set_43,
418      44 => RE_SetU_44,
419      45 => RE_Set_45,
420      46 => RE_SetU_46,
421      47 => RE_Set_47,
422      48 => RE_SetU_48,
423      49 => RE_Set_49,
424      50 => RE_SetU_50,
425      51 => RE_Set_51,
426      52 => RE_SetU_52,
427      53 => RE_Set_53,
428      54 => RE_SetU_54,
429      55 => RE_Set_55,
430      56 => RE_SetU_56,
431      57 => RE_Set_57,
432      58 => RE_SetU_58,
433      59 => RE_Set_59,
434      60 => RE_SetU_60,
435      61 => RE_Set_61,
436      62 => RE_SetU_62,
437      63 => RE_Set_63);
438
439   -----------------------
440   -- Local Subprograms --
441   -----------------------
442
443   procedure Compute_Linear_Subscript
444     (Atyp   : Entity_Id;
445      N      : Node_Id;
446      Subscr : out Node_Id);
447   --  Given a constrained array type Atyp, and an indexed component node N
448   --  referencing an array object of this type, build an expression of type
449   --  Standard.Integer representing the zero-based linear subscript value.
450   --  This expression includes any required range checks.
451
452   procedure Convert_To_PAT_Type (Aexp : Node_Id);
453   --  Given an expression of a packed array type, builds a corresponding
454   --  expression whose type is the implementation type used to represent
455   --  the packed array. Aexp is analyzed and resolved on entry and on exit.
456
457   procedure Get_Base_And_Bit_Offset
458     (N      : Node_Id;
459      Base   : out Node_Id;
460      Offset : out Node_Id);
461   --  Given a node N for a name which involves a packed array reference,
462   --  return the base object of the reference and build an expression of
463   --  type Standard.Integer representing the zero-based offset in bits
464   --  from Base'Address to the first bit of the reference.
465
466   function Known_Aligned_Enough (Obj : Node_Id; Csiz : Nat) return Boolean;
467   --  There are two versions of the Set routines, the ones used when the
468   --  object is known to be sufficiently well aligned given the number of
469   --  bits, and the ones used when the object is not known to be aligned.
470   --  This routine is used to determine which set to use. Obj is a reference
471   --  to the object, and Csiz is the component size of the packed array.
472   --  True is returned if the alignment of object is known to be sufficient,
473   --  defined as 1 for odd bit sizes, 4 for bit sizes divisible by 4, and
474   --  2 otherwise.
475
476   function Make_Shift_Left (N : Node_Id; S : Node_Id) return Node_Id;
477   --  Build a left shift node, checking for the case of a shift count of zero
478
479   function Make_Shift_Right (N : Node_Id; S : Node_Id) return Node_Id;
480   --  Build a right shift node, checking for the case of a shift count of zero
481
482   function RJ_Unchecked_Convert_To
483     (Typ  : Entity_Id;
484      Expr : Node_Id) return Node_Id;
485   --  The packed array code does unchecked conversions which in some cases
486   --  may involve non-discrete types with differing sizes. The semantics of
487   --  such conversions is potentially endian dependent, and the effect we
488   --  want here for such a conversion is to do the conversion in size as
489   --  though numeric items are involved, and we extend or truncate on the
490   --  left side. This happens naturally in the little-endian case, but in
491   --  the big endian case we can get left justification, when what we want
492   --  is right justification. This routine does the unchecked conversion in
493   --  a stepwise manner to ensure that it gives the expected result. Hence
494   --  the name (RJ = Right justified). The parameters Typ and Expr are as
495   --  for the case of a normal Unchecked_Convert_To call.
496
497   procedure Setup_Enumeration_Packed_Array_Reference (N : Node_Id);
498   --  This routine is called in the Get and Set case for arrays that are
499   --  packed but not bit-packed, meaning that they have at least one
500   --  subscript that is of an enumeration type with a non-standard
501   --  representation. This routine modifies the given node to properly
502   --  reference the corresponding packed array type.
503
504   procedure Setup_Inline_Packed_Array_Reference
505     (N      : Node_Id;
506      Atyp   : Entity_Id;
507      Obj    : in out Node_Id;
508      Cmask  : out Uint;
509      Shift  : out Node_Id);
510   --  This procedure performs common processing on the N_Indexed_Component
511   --  parameter given as N, whose prefix is a reference to a packed array.
512   --  This is used for the get and set when the component size is 1, 2, 4,
513   --  or for other component sizes when the packed array type is a modular
514   --  type (i.e. the cases that are handled with inline code).
515   --
516   --  On entry:
517   --
518   --    N is the N_Indexed_Component node for the packed array reference
519   --
520   --    Atyp is the constrained array type (the actual subtype has been
521   --    computed if necessary to obtain the constraints, but this is still
522   --    the original array type, not the Packed_Array_Type value).
523   --
524   --    Obj is the object which is to be indexed. It is always of type Atyp.
525   --
526   --  On return:
527   --
528   --    Obj is the object containing the desired bit field. It is of type
529   --    Unsigned, Long_Unsigned, or Long_Long_Unsigned, and is either the
530   --    entire value, for the small static case, or the proper selected byte
531   --    from the array in the large or dynamic case. This node is analyzed
532   --    and resolved on return.
533   --
534   --    Shift is a node representing the shift count to be used in the
535   --    rotate right instruction that positions the field for access.
536   --    This node is analyzed and resolved on return.
537   --
538   --    Cmask is a mask corresponding to the width of the component field.
539   --    Its value is 2 ** Csize - 1 (e.g. 2#1111# for component size of 4).
540   --
541   --  Note: in some cases the call to this routine may generate actions
542   --  (for handling multi-use references and the generation of the packed
543   --  array type on the fly). Such actions are inserted into the tree
544   --  directly using Insert_Action.
545
546   function Byte_Swap (N : Node_Id) return Node_Id;
547   --  Wrap N in a call to a byte swapping function, with appropriate type
548   --  conversions.
549
550   ---------------
551   -- Byte_Swap --
552   ---------------
553
554   function Byte_Swap (N : Node_Id) return Node_Id is
555      Loc     : constant Source_Ptr := Sloc (N);
556      T       : constant Entity_Id := Etype (N);
557      Swap_RE : RE_Id;
558      Swap_F  : Entity_Id;
559
560   begin
561      pragma Assert (Esize (T) > 8);
562
563      if Esize (T) <= 16 then
564         Swap_RE := RE_Bswap_16;
565      elsif Esize (T) <= 32 then
566         Swap_RE := RE_Bswap_32;
567      else pragma Assert (Esize (T) <= 64);
568         Swap_RE := RE_Bswap_64;
569      end if;
570
571      Swap_F := RTE (Swap_RE);
572
573      return
574        Unchecked_Convert_To (T,
575          Make_Function_Call (Loc,
576            Name                   => New_Occurrence_Of (Swap_F, Loc),
577            Parameter_Associations =>
578              New_List (Unchecked_Convert_To (Etype (Swap_F), N))));
579   end Byte_Swap;
580
581   ------------------------------
582   -- Compute_Linear_Subscript --
583   ------------------------------
584
585   procedure Compute_Linear_Subscript
586     (Atyp   : Entity_Id;
587      N      : Node_Id;
588      Subscr : out Node_Id)
589   is
590      Loc    : constant Source_Ptr := Sloc (N);
591      Oldsub : Node_Id;
592      Newsub : Node_Id;
593      Indx   : Node_Id;
594      Styp   : Entity_Id;
595
596   begin
597      Subscr := Empty;
598
599      --  Loop through dimensions
600
601      Indx   := First_Index (Atyp);
602      Oldsub := First (Expressions (N));
603
604      while Present (Indx) loop
605         Styp := Etype (Indx);
606         Newsub := Relocate_Node (Oldsub);
607
608         --  Get expression for the subscript value. First, if Do_Range_Check
609         --  is set on a subscript, then we must do a range check against the
610         --  original bounds (not the bounds of the packed array type). We do
611         --  this by introducing a subtype conversion.
612
613         if Do_Range_Check (Newsub)
614           and then Etype (Newsub) /= Styp
615         then
616            Newsub := Convert_To (Styp, Newsub);
617         end if;
618
619         --  Now evolve the expression for the subscript. First convert
620         --  the subscript to be zero based and of an integer type.
621
622         --  Case of integer type, where we just subtract to get lower bound
623
624         if Is_Integer_Type (Styp) then
625
626            --  If length of integer type is smaller than standard integer,
627            --  then we convert to integer first, then do the subtract
628
629            --  Integer (subscript) - Integer (Styp'First)
630
631            if Esize (Styp) < Esize (Standard_Integer) then
632               Newsub :=
633                 Make_Op_Subtract (Loc,
634                   Left_Opnd => Convert_To (Standard_Integer, Newsub),
635                 Right_Opnd =>
636                   Convert_To (Standard_Integer,
637                     Make_Attribute_Reference (Loc,
638                       Prefix         => New_Occurrence_Of (Styp, Loc),
639                       Attribute_Name => Name_First)));
640
641            --  For larger integer types, subtract first, then convert to
642            --  integer, this deals with strange long long integer bounds.
643
644            --    Integer (subscript - Styp'First)
645
646            else
647               Newsub :=
648                 Convert_To (Standard_Integer,
649                   Make_Op_Subtract (Loc,
650                     Left_Opnd => Newsub,
651                   Right_Opnd =>
652                     Make_Attribute_Reference (Loc,
653                       Prefix         => New_Occurrence_Of (Styp, Loc),
654                       Attribute_Name => Name_First)));
655            end if;
656
657         --  For the enumeration case, we have to use 'Pos to get the value
658         --  to work with before subtracting the lower bound.
659
660         --    Integer (Styp'Pos (subscr)) - Integer (Styp'Pos (Styp'First));
661
662         --  This is not quite right for bizarre cases where the size of the
663         --  enumeration type is > Integer'Size bits due to rep clause ???
664
665         else
666            pragma Assert (Is_Enumeration_Type (Styp));
667
668            Newsub :=
669              Make_Op_Subtract (Loc,
670                Left_Opnd => Convert_To (Standard_Integer,
671                  Make_Attribute_Reference (Loc,
672                    Prefix         => New_Occurrence_Of (Styp, Loc),
673                    Attribute_Name => Name_Pos,
674                    Expressions    => New_List (Newsub))),
675
676                Right_Opnd =>
677                  Convert_To (Standard_Integer,
678                    Make_Attribute_Reference (Loc,
679                      Prefix         => New_Occurrence_Of (Styp, Loc),
680                      Attribute_Name => Name_Pos,
681                      Expressions    => New_List (
682                        Make_Attribute_Reference (Loc,
683                          Prefix         => New_Occurrence_Of (Styp, Loc),
684                          Attribute_Name => Name_First)))));
685         end if;
686
687         Set_Paren_Count (Newsub, 1);
688
689         --  For the first subscript, we just copy that subscript value
690
691         if No (Subscr) then
692            Subscr := Newsub;
693
694         --  Otherwise, we must multiply what we already have by the current
695         --  stride and then add in the new value to the evolving subscript.
696
697         else
698            Subscr :=
699              Make_Op_Add (Loc,
700                Left_Opnd =>
701                  Make_Op_Multiply (Loc,
702                    Left_Opnd  => Subscr,
703                    Right_Opnd =>
704                      Make_Attribute_Reference (Loc,
705                        Attribute_Name => Name_Range_Length,
706                        Prefix         => New_Occurrence_Of (Styp, Loc))),
707                Right_Opnd => Newsub);
708         end if;
709
710         --  Move to next subscript
711
712         Next_Index (Indx);
713         Next (Oldsub);
714      end loop;
715   end Compute_Linear_Subscript;
716
717   -------------------------
718   -- Convert_To_PAT_Type --
719   -------------------------
720
721   --  The PAT is always obtained from the actual subtype
722
723   procedure Convert_To_PAT_Type (Aexp : Node_Id) is
724      Act_ST : Entity_Id;
725
726   begin
727      Convert_To_Actual_Subtype (Aexp);
728      Act_ST := Underlying_Type (Etype (Aexp));
729      Create_Packed_Array_Type (Act_ST);
730
731      --  Just replace the etype with the packed array type. This works because
732      --  the expression will not be further analyzed, and Gigi considers the
733      --  two types equivalent in any case.
734
735      --  This is not strictly the case ??? If the reference is an actual in
736      --  call, the expansion of the prefix is delayed, and must be reanalyzed,
737      --  see Reset_Packed_Prefix. On the other hand, if the prefix is a simple
738      --  array reference, reanalysis can produce spurious type errors when the
739      --  PAT type is replaced again with the original type of the array. Same
740      --  for the case of a dereference. Ditto for function calls: expansion
741      --  may introduce additional actuals which will trigger errors if call is
742      --  reanalyzed. The following is correct and minimal, but the handling of
743      --  more complex packed expressions in actuals is confused. Probably the
744      --  problem only remains for actuals in calls.
745
746      Set_Etype (Aexp, Packed_Array_Type (Act_ST));
747
748      if Is_Entity_Name (Aexp)
749        or else
750           (Nkind (Aexp) = N_Indexed_Component
751             and then Is_Entity_Name (Prefix (Aexp)))
752        or else Nkind_In (Aexp, N_Explicit_Dereference, N_Function_Call)
753      then
754         Set_Analyzed (Aexp);
755      end if;
756   end Convert_To_PAT_Type;
757
758   ------------------------------
759   -- Create_Packed_Array_Type --
760   ------------------------------
761
762   procedure Create_Packed_Array_Type (Typ : Entity_Id) is
763      Loc      : constant Source_Ptr := Sloc (Typ);
764      Ctyp     : constant Entity_Id  := Component_Type (Typ);
765      Csize    : constant Uint       := Component_Size (Typ);
766
767      Ancest   : Entity_Id;
768      PB_Type  : Entity_Id;
769      PASize   : Uint;
770      Decl     : Node_Id;
771      PAT      : Entity_Id;
772      Len_Dim  : Node_Id;
773      Len_Expr : Node_Id;
774      Len_Bits : Uint;
775      Bits_U1  : Node_Id;
776      PAT_High : Node_Id;
777      Btyp     : Entity_Id;
778      Lit      : Node_Id;
779
780      procedure Install_PAT;
781      --  This procedure is called with Decl set to the declaration for the
782      --  packed array type. It creates the type and installs it as required.
783
784      procedure Set_PB_Type;
785      --  Sets PB_Type to Packed_Bytes{1,2,4} as required by the alignment
786      --  requirements (see documentation in the spec of this package).
787
788      -----------------
789      -- Install_PAT --
790      -----------------
791
792      procedure Install_PAT is
793         Pushed_Scope : Boolean := False;
794
795      begin
796         --  We do not want to put the declaration we have created in the tree
797         --  since it is often hard, and sometimes impossible to find a proper
798         --  place for it (the impossible case arises for a packed array type
799         --  with bounds depending on the discriminant, a declaration cannot
800         --  be put inside the record, and the reference to the discriminant
801         --  cannot be outside the record).
802
803         --  The solution is to analyze the declaration while temporarily
804         --  attached to the tree at an appropriate point, and then we install
805         --  the resulting type as an Itype in the packed array type field of
806         --  the original type, so that no explicit declaration is required.
807
808         --  Note: the packed type is created in the scope of its parent
809         --  type. There are at least some cases where the current scope
810         --  is deeper, and so when this is the case, we temporarily reset
811         --  the scope for the definition. This is clearly safe, since the
812         --  first use of the packed array type will be the implicit
813         --  reference from the corresponding unpacked type when it is
814         --  elaborated.
815
816         if Is_Itype (Typ) then
817            Set_Parent (Decl, Associated_Node_For_Itype (Typ));
818         else
819            Set_Parent (Decl, Declaration_Node (Typ));
820         end if;
821
822         if Scope (Typ) /= Current_Scope then
823            Push_Scope (Scope (Typ));
824            Pushed_Scope := True;
825         end if;
826
827         Set_Is_Itype (PAT, True);
828         Set_Packed_Array_Type (Typ, PAT);
829         Analyze (Decl, Suppress => All_Checks);
830
831         if Pushed_Scope then
832            Pop_Scope;
833         end if;
834
835         --  Set Esize and RM_Size to the actual size of the packed object
836         --  Do not reset RM_Size if already set, as happens in the case of
837         --  a modular type.
838
839         if Unknown_Esize (PAT) then
840            Set_Esize (PAT, PASize);
841         end if;
842
843         if Unknown_RM_Size (PAT) then
844            Set_RM_Size (PAT, PASize);
845         end if;
846
847         Adjust_Esize_Alignment (PAT);
848
849         --  Set remaining fields of packed array type
850
851         Init_Alignment                (PAT);
852         Set_Parent                    (PAT, Empty);
853         Set_Associated_Node_For_Itype (PAT, Typ);
854         Set_Is_Packed_Array_Type      (PAT, True);
855         Set_Original_Array_Type       (PAT, Typ);
856
857         --  We definitely do not want to delay freezing for packed array
858         --  types. This is of particular importance for the itypes that
859         --  are generated for record components depending on discriminants
860         --  where there is no place to put the freeze node.
861
862         Set_Has_Delayed_Freeze (PAT, False);
863         Set_Has_Delayed_Freeze (Etype (PAT), False);
864
865         --  If we did allocate a freeze node, then clear out the reference
866         --  since it is obsolete (should we delete the freeze node???)
867
868         Set_Freeze_Node (PAT, Empty);
869         Set_Freeze_Node (Etype (PAT), Empty);
870      end Install_PAT;
871
872      -----------------
873      -- Set_PB_Type --
874      -----------------
875
876      procedure Set_PB_Type is
877      begin
878         --  If the user has specified an explicit alignment for the
879         --  type or component, take it into account.
880
881         if Csize <= 2 or else Csize = 4 or else Csize mod 2 /= 0
882           or else Alignment (Typ) = 1
883           or else Component_Alignment (Typ) = Calign_Storage_Unit
884         then
885            PB_Type := RTE (RE_Packed_Bytes1);
886
887         elsif Csize mod 4 /= 0
888           or else Alignment (Typ) = 2
889         then
890            PB_Type := RTE (RE_Packed_Bytes2);
891
892         else
893            PB_Type := RTE (RE_Packed_Bytes4);
894         end if;
895      end Set_PB_Type;
896
897   --  Start of processing for Create_Packed_Array_Type
898
899   begin
900      --  If we already have a packed array type, nothing to do
901
902      if Present (Packed_Array_Type (Typ)) then
903         return;
904      end if;
905
906      --  If our immediate ancestor subtype is constrained, and it already
907      --  has a packed array type, then just share the same type, since the
908      --  bounds must be the same. If the ancestor is not an array type but
909      --  a private type, as can happen with multiple instantiations, create
910      --  a new packed type, to avoid privacy issues.
911
912      if Ekind (Typ) = E_Array_Subtype then
913         Ancest := Ancestor_Subtype (Typ);
914
915         if Present (Ancest)
916           and then Is_Array_Type (Ancest)
917           and then Is_Constrained (Ancest)
918           and then Present (Packed_Array_Type (Ancest))
919         then
920            Set_Packed_Array_Type (Typ, Packed_Array_Type (Ancest));
921            return;
922         end if;
923      end if;
924
925      --  We preset the result type size from the size of the original array
926      --  type, since this size clearly belongs to the packed array type. The
927      --  size of the conceptual unpacked type is always set to unknown.
928
929      PASize := RM_Size (Typ);
930
931      --  Case of an array where at least one index is of an enumeration
932      --  type with a non-standard representation, but the component size
933      --  is not appropriate for bit packing. This is the case where we
934      --  have Is_Packed set (we would never be in this unit otherwise),
935      --  but Is_Bit_Packed_Array is false.
936
937      --  Note that if the component size is appropriate for bit packing,
938      --  then the circuit for the computation of the subscript properly
939      --  deals with the non-standard enumeration type case by taking the
940      --  Pos anyway.
941
942      if not Is_Bit_Packed_Array (Typ) then
943
944         --  Here we build a declaration:
945
946         --    type tttP is array (index1, index2, ...) of component_type
947
948         --  where index1, index2, are the index types. These are the same
949         --  as the index types of the original array, except for the non-
950         --  standard representation enumeration type case, where we have
951         --  two subcases.
952
953         --  For the unconstrained array case, we use
954
955         --    Natural range <>
956
957         --  For the constrained case, we use
958
959         --    Natural range Enum_Type'Pos (Enum_Type'First) ..
960         --                  Enum_Type'Pos (Enum_Type'Last);
961
962         PAT :=
963           Make_Defining_Identifier (Loc,
964             Chars => New_External_Name (Chars (Typ), 'P'));
965
966         Set_Packed_Array_Type (Typ, PAT);
967
968         declare
969            Indexes   : constant List_Id := New_List;
970            Indx      : Node_Id;
971            Indx_Typ  : Entity_Id;
972            Enum_Case : Boolean;
973            Typedef   : Node_Id;
974
975         begin
976            Indx := First_Index (Typ);
977
978            while Present (Indx) loop
979               Indx_Typ := Etype (Indx);
980
981               Enum_Case := Is_Enumeration_Type (Indx_Typ)
982                              and then Has_Non_Standard_Rep (Indx_Typ);
983
984               --  Unconstrained case
985
986               if not Is_Constrained (Typ) then
987                  if Enum_Case then
988                     Indx_Typ := Standard_Natural;
989                  end if;
990
991                  Append_To (Indexes, New_Occurrence_Of (Indx_Typ, Loc));
992
993               --  Constrained case
994
995               else
996                  if not Enum_Case then
997                     Append_To (Indexes, New_Occurrence_Of (Indx_Typ, Loc));
998
999                  else
1000                     Append_To (Indexes,
1001                       Make_Subtype_Indication (Loc,
1002                         Subtype_Mark =>
1003                           New_Occurrence_Of (Standard_Natural, Loc),
1004                         Constraint =>
1005                           Make_Range_Constraint (Loc,
1006                             Range_Expression =>
1007                               Make_Range (Loc,
1008                                 Low_Bound =>
1009                                   Make_Attribute_Reference (Loc,
1010                                     Prefix         =>
1011                                       New_Occurrence_Of (Indx_Typ, Loc),
1012                                     Attribute_Name => Name_Pos,
1013                                     Expressions    => New_List (
1014                                       Make_Attribute_Reference (Loc,
1015                                         Prefix         =>
1016                                           New_Occurrence_Of (Indx_Typ, Loc),
1017                                         Attribute_Name => Name_First))),
1018
1019                                 High_Bound =>
1020                                   Make_Attribute_Reference (Loc,
1021                                     Prefix         =>
1022                                       New_Occurrence_Of (Indx_Typ, Loc),
1023                                     Attribute_Name => Name_Pos,
1024                                     Expressions    => New_List (
1025                                       Make_Attribute_Reference (Loc,
1026                                         Prefix         =>
1027                                           New_Occurrence_Of (Indx_Typ, Loc),
1028                                         Attribute_Name => Name_Last)))))));
1029
1030                  end if;
1031               end if;
1032
1033               Next_Index (Indx);
1034            end loop;
1035
1036            if not Is_Constrained (Typ) then
1037               Typedef :=
1038                 Make_Unconstrained_Array_Definition (Loc,
1039                   Subtype_Marks => Indexes,
1040                   Component_Definition =>
1041                     Make_Component_Definition (Loc,
1042                       Aliased_Present    => False,
1043                       Subtype_Indication =>
1044                          New_Occurrence_Of (Ctyp, Loc)));
1045
1046            else
1047               Typedef :=
1048                  Make_Constrained_Array_Definition (Loc,
1049                    Discrete_Subtype_Definitions => Indexes,
1050                    Component_Definition =>
1051                      Make_Component_Definition (Loc,
1052                        Aliased_Present    => False,
1053                        Subtype_Indication =>
1054                          New_Occurrence_Of (Ctyp, Loc)));
1055            end if;
1056
1057            Decl :=
1058              Make_Full_Type_Declaration (Loc,
1059                Defining_Identifier => PAT,
1060                Type_Definition => Typedef);
1061         end;
1062
1063         --  Set type as packed array type and install it
1064
1065         Set_Is_Packed_Array_Type (PAT);
1066         Install_PAT;
1067         return;
1068
1069      --  Case of bit-packing required for unconstrained array. We create
1070      --  a subtype that is equivalent to use Packed_Bytes{1,2,4} as needed.
1071
1072      elsif not Is_Constrained (Typ) then
1073         PAT :=
1074           Make_Defining_Identifier (Loc,
1075             Chars => Make_Packed_Array_Type_Name (Typ, Csize));
1076
1077         Set_Packed_Array_Type (Typ, PAT);
1078         Set_PB_Type;
1079
1080         Decl :=
1081           Make_Subtype_Declaration (Loc,
1082             Defining_Identifier => PAT,
1083               Subtype_Indication => New_Occurrence_Of (PB_Type, Loc));
1084         Install_PAT;
1085         return;
1086
1087      --  Remaining code is for the case of bit-packing for constrained array
1088
1089      --  The name of the packed array subtype is
1090
1091      --    ttt___Xsss
1092
1093      --  where sss is the component size in bits and ttt is the name of
1094      --  the parent packed type.
1095
1096      else
1097         PAT :=
1098           Make_Defining_Identifier (Loc,
1099             Chars => Make_Packed_Array_Type_Name (Typ, Csize));
1100
1101         Set_Packed_Array_Type (Typ, PAT);
1102
1103         --  Build an expression for the length of the array in bits.
1104         --  This is the product of the length of each of the dimensions
1105
1106         declare
1107            J : Nat := 1;
1108
1109         begin
1110            Len_Expr := Empty; -- suppress junk warning
1111
1112            loop
1113               Len_Dim :=
1114                 Make_Attribute_Reference (Loc,
1115                   Attribute_Name => Name_Length,
1116                   Prefix         => New_Occurrence_Of (Typ, Loc),
1117                   Expressions    => New_List (
1118                     Make_Integer_Literal (Loc, J)));
1119
1120               if J = 1 then
1121                  Len_Expr := Len_Dim;
1122
1123               else
1124                  Len_Expr :=
1125                    Make_Op_Multiply (Loc,
1126                      Left_Opnd  => Len_Expr,
1127                      Right_Opnd => Len_Dim);
1128               end if;
1129
1130               J := J + 1;
1131               exit when J > Number_Dimensions (Typ);
1132            end loop;
1133         end;
1134
1135         --  Temporarily attach the length expression to the tree and analyze
1136         --  and resolve it, so that we can test its value. We assume that the
1137         --  total length fits in type Integer. This expression may involve
1138         --  discriminants, so we treat it as a default/per-object expression.
1139
1140         Set_Parent (Len_Expr, Typ);
1141         Preanalyze_Spec_Expression (Len_Expr, Standard_Long_Long_Integer);
1142
1143         --  Use a modular type if possible. We can do this if we have
1144         --  static bounds, and the length is small enough, and the length
1145         --  is not zero. We exclude the zero length case because the size
1146         --  of things is always at least one, and the zero length object
1147         --  would have an anomalous size.
1148
1149         if Compile_Time_Known_Value (Len_Expr) then
1150            Len_Bits := Expr_Value (Len_Expr) * Csize;
1151
1152            --  Check for size known to be too large
1153
1154            if Len_Bits >
1155              Uint_2 ** (Standard_Integer_Size - 1) * System_Storage_Unit
1156            then
1157               if System_Storage_Unit = 8 then
1158                  Error_Msg_N
1159                    ("packed array size cannot exceed " &
1160                     "Integer''Last bytes", Typ);
1161               else
1162                  Error_Msg_N
1163                    ("packed array size cannot exceed " &
1164                     "Integer''Last storage units", Typ);
1165               end if;
1166
1167               --  Reset length to arbitrary not too high value to continue
1168
1169               Len_Expr := Make_Integer_Literal (Loc, 65535);
1170               Analyze_And_Resolve (Len_Expr, Standard_Long_Long_Integer);
1171            end if;
1172
1173            --  We normally consider small enough to mean no larger than the
1174            --  value of System_Max_Binary_Modulus_Power, checking that in the
1175            --  case of values longer than word size, we have long shifts.
1176
1177            if Len_Bits > 0
1178              and then
1179                (Len_Bits <= System_Word_Size
1180                   or else (Len_Bits <= System_Max_Binary_Modulus_Power
1181                              and then Support_Long_Shifts_On_Target))
1182            then
1183               --  We can use the modular type, it has the form:
1184
1185               --    subtype tttPn is btyp
1186               --      range 0 .. 2 ** ((Typ'Length (1)
1187               --                * ... * Typ'Length (n)) * Csize) - 1;
1188
1189               --  The bounds are statically known, and btyp is one of the
1190               --  unsigned types, depending on the length.
1191
1192               if Len_Bits <= Standard_Short_Short_Integer_Size then
1193                  Btyp := RTE (RE_Short_Short_Unsigned);
1194
1195               elsif Len_Bits <= Standard_Short_Integer_Size then
1196                  Btyp := RTE (RE_Short_Unsigned);
1197
1198               elsif Len_Bits <= Standard_Integer_Size then
1199                  Btyp := RTE (RE_Unsigned);
1200
1201               elsif Len_Bits <= Standard_Long_Integer_Size then
1202                  Btyp := RTE (RE_Long_Unsigned);
1203
1204               else
1205                  Btyp := RTE (RE_Long_Long_Unsigned);
1206               end if;
1207
1208               Lit := Make_Integer_Literal (Loc, 2 ** Len_Bits - 1);
1209               Set_Print_In_Hex (Lit);
1210
1211               Decl :=
1212                 Make_Subtype_Declaration (Loc,
1213                   Defining_Identifier => PAT,
1214                     Subtype_Indication =>
1215                       Make_Subtype_Indication (Loc,
1216                         Subtype_Mark => New_Occurrence_Of (Btyp, Loc),
1217
1218                         Constraint =>
1219                           Make_Range_Constraint (Loc,
1220                             Range_Expression =>
1221                               Make_Range (Loc,
1222                                 Low_Bound =>
1223                                   Make_Integer_Literal (Loc, 0),
1224                                 High_Bound => Lit))));
1225
1226               if PASize = Uint_0 then
1227                  PASize := Len_Bits;
1228               end if;
1229
1230               Install_PAT;
1231
1232               --  Propagate a given alignment to the modular type. This can
1233               --  cause it to be under-aligned, but that's OK.
1234
1235               if Present (Alignment_Clause (Typ)) then
1236                  Set_Alignment (PAT, Alignment (Typ));
1237               end if;
1238
1239               return;
1240            end if;
1241         end if;
1242
1243         --  Could not use a modular type, for all other cases, we build
1244         --  a packed array subtype:
1245
1246         --    subtype tttPn is
1247         --      System.Packed_Bytes{1,2,4} (0 .. (Bits + 7) / 8 - 1);
1248
1249         --  Bits is the length of the array in bits
1250
1251         Set_PB_Type;
1252
1253         Bits_U1 :=
1254           Make_Op_Add (Loc,
1255             Left_Opnd =>
1256               Make_Op_Multiply (Loc,
1257                 Left_Opnd  =>
1258                   Make_Integer_Literal (Loc, Csize),
1259                 Right_Opnd => Len_Expr),
1260
1261             Right_Opnd =>
1262               Make_Integer_Literal (Loc, 7));
1263
1264         Set_Paren_Count (Bits_U1, 1);
1265
1266         PAT_High :=
1267           Make_Op_Subtract (Loc,
1268             Left_Opnd =>
1269               Make_Op_Divide (Loc,
1270                 Left_Opnd => Bits_U1,
1271                 Right_Opnd => Make_Integer_Literal (Loc, 8)),
1272             Right_Opnd => Make_Integer_Literal (Loc, 1));
1273
1274         Decl :=
1275           Make_Subtype_Declaration (Loc,
1276             Defining_Identifier => PAT,
1277               Subtype_Indication =>
1278                 Make_Subtype_Indication (Loc,
1279                   Subtype_Mark => New_Occurrence_Of (PB_Type, Loc),
1280                   Constraint =>
1281                     Make_Index_Or_Discriminant_Constraint (Loc,
1282                       Constraints => New_List (
1283                         Make_Range (Loc,
1284                           Low_Bound =>
1285                             Make_Integer_Literal (Loc, 0),
1286                           High_Bound =>
1287                             Convert_To (Standard_Integer, PAT_High))))));
1288
1289         Install_PAT;
1290
1291         --  Currently the code in this unit requires that packed arrays
1292         --  represented by non-modular arrays of bytes be on a byte
1293         --  boundary for bit sizes handled by System.Pack_nn units.
1294         --  That's because these units assume the array being accessed
1295         --  starts on a byte boundary.
1296
1297         if Get_Id (UI_To_Int (Csize)) /= RE_Null then
1298            Set_Must_Be_On_Byte_Boundary (Typ);
1299         end if;
1300      end if;
1301   end Create_Packed_Array_Type;
1302
1303   -----------------------------------
1304   -- Expand_Bit_Packed_Element_Set --
1305   -----------------------------------
1306
1307   procedure Expand_Bit_Packed_Element_Set (N : Node_Id) is
1308      Loc : constant Source_Ptr := Sloc (N);
1309      Lhs : constant Node_Id    := Name (N);
1310
1311      Ass_OK : constant Boolean := Assignment_OK (Lhs);
1312      --  Used to preserve assignment OK status when assignment is rewritten
1313
1314      Rhs : Node_Id := Expression (N);
1315      --  Initially Rhs is the right hand side value, it will be replaced
1316      --  later by an appropriate unchecked conversion for the assignment.
1317
1318      Obj   : Node_Id;
1319      Atyp  : Entity_Id;
1320      PAT   : Entity_Id;
1321      Ctyp  : Entity_Id;
1322      Csiz  : Int;
1323      Cmask : Uint;
1324
1325      Shift : Node_Id;
1326      --  The expression for the shift value that is required
1327
1328      Shift_Used : Boolean := False;
1329      --  Set True if Shift has been used in the generated code at least
1330      --  once, so that it must be duplicated if used again
1331
1332      New_Lhs : Node_Id;
1333      New_Rhs : Node_Id;
1334
1335      Rhs_Val_Known : Boolean;
1336      Rhs_Val       : Uint;
1337      --  If the value of the right hand side as an integer constant is
1338      --  known at compile time, Rhs_Val_Known is set True, and Rhs_Val
1339      --  contains the value. Otherwise Rhs_Val_Known is set False, and
1340      --  the Rhs_Val is undefined.
1341
1342      Require_Byte_Swapping : Boolean := False;
1343      --  True if byte swapping required, for the Reverse_Storage_Order case
1344      --  when the packed array is a free-standing object. (If it is part
1345      --  of a composite type, and therefore potentially not aligned on a byte
1346      --  boundary, the swapping is done by the back-end).
1347
1348      function Get_Shift return Node_Id;
1349      --  Function used to get the value of Shift, making sure that it
1350      --  gets duplicated if the function is called more than once.
1351
1352      ---------------
1353      -- Get_Shift --
1354      ---------------
1355
1356      function Get_Shift return Node_Id is
1357      begin
1358         --  If we used the shift value already, then duplicate it. We
1359         --  set a temporary parent in case actions have to be inserted.
1360
1361         if Shift_Used then
1362            Set_Parent (Shift, N);
1363            return Duplicate_Subexpr_No_Checks (Shift);
1364
1365         --  If first time, use Shift unchanged, and set flag for first use
1366
1367         else
1368            Shift_Used := True;
1369            return Shift;
1370         end if;
1371      end Get_Shift;
1372
1373   --  Start of processing for Expand_Bit_Packed_Element_Set
1374
1375   begin
1376      pragma Assert (Is_Bit_Packed_Array (Etype (Prefix (Lhs))));
1377
1378      Obj := Relocate_Node (Prefix (Lhs));
1379      Convert_To_Actual_Subtype (Obj);
1380      Atyp := Etype (Obj);
1381      PAT  := Packed_Array_Type (Atyp);
1382      Ctyp := Component_Type (Atyp);
1383      Csiz := UI_To_Int (Component_Size (Atyp));
1384
1385      --  We remove side effects, in case the rhs modifies the lhs, because we
1386      --  are about to transform the rhs into an expression that first READS
1387      --  the lhs, so we can do the necessary shifting and masking. Example:
1388      --  "X(2) := F(...);" where F modifies X(3). Otherwise, the side effect
1389      --  will be lost.
1390
1391      Remove_Side_Effects (Rhs);
1392
1393      --  We convert the right hand side to the proper subtype to ensure
1394      --  that an appropriate range check is made (since the normal range
1395      --  check from assignment will be lost in the transformations). This
1396      --  conversion is analyzed immediately so that subsequent processing
1397      --  can work with an analyzed Rhs (and e.g. look at its Etype)
1398
1399      --  If the right-hand side is a string literal, create a temporary for
1400      --  it, constant-folding is not ready to wrap the bit representation
1401      --  of a string literal.
1402
1403      if Nkind (Rhs) = N_String_Literal then
1404         declare
1405            Decl : Node_Id;
1406         begin
1407            Decl :=
1408              Make_Object_Declaration (Loc,
1409                Defining_Identifier => Make_Temporary (Loc, 'T', Rhs),
1410                Object_Definition   => New_Occurrence_Of (Ctyp, Loc),
1411                Expression          => New_Copy_Tree (Rhs));
1412
1413            Insert_Actions (N, New_List (Decl));
1414            Rhs := New_Occurrence_Of (Defining_Identifier (Decl), Loc);
1415         end;
1416      end if;
1417
1418      Rhs := Convert_To (Ctyp, Rhs);
1419      Set_Parent (Rhs, N);
1420
1421      --  If we are building the initialization procedure for a packed array,
1422      --  and Initialize_Scalars is enabled, each component assignment is an
1423      --  out-of-range value by design.  Compile this value without checks,
1424      --  because a call to the array init_proc must not raise an exception.
1425
1426      if Within_Init_Proc
1427        and then Initialize_Scalars
1428      then
1429         Analyze_And_Resolve (Rhs, Ctyp, Suppress => All_Checks);
1430      else
1431         Analyze_And_Resolve (Rhs, Ctyp);
1432      end if;
1433
1434      --  For the AAMP target, indexing of certain packed array is passed
1435      --  through to the back end without expansion, because the expansion
1436      --  results in very inefficient code on that target. This allows the
1437      --  GNAAMP back end to generate specialized macros that support more
1438      --  efficient indexing of packed arrays with components having sizes
1439      --  that are small powers of two.
1440
1441      if AAMP_On_Target
1442        and then (Csiz = 1 or else Csiz = 2 or else Csiz = 4)
1443      then
1444         return;
1445      end if;
1446
1447      --  Case of component size 1,2,4 or any component size for the modular
1448      --  case. These are the cases for which we can inline the code.
1449
1450      if Csiz = 1 or else Csiz = 2 or else Csiz = 4
1451        or else (Present (PAT) and then Is_Modular_Integer_Type (PAT))
1452      then
1453         Setup_Inline_Packed_Array_Reference (Lhs, Atyp, Obj, Cmask, Shift);
1454
1455         --  The statement to be generated is:
1456
1457         --    Obj := atyp!((Obj and Mask1) or (shift_left (rhs, Shift)))
1458
1459         --  or in the case of a freestanding Reverse_Storage_Order object,
1460
1461         --    Obj := Swap (atyp!((Swap (Obj) and Mask1)
1462         --                         or (shift_left (rhs, Shift))))
1463
1464         --      where Mask1 is obtained by shifting Cmask left Shift bits
1465         --      and then complementing the result.
1466
1467         --      the "and Mask1" is omitted if rhs is constant and all 1 bits
1468
1469         --      the "or ..." is omitted if rhs is constant and all 0 bits
1470
1471         --      rhs is converted to the appropriate type
1472
1473         --      The result is converted back to the array type, since
1474         --      otherwise we lose knowledge of the packed nature.
1475
1476         --  Determine if right side is all 0 bits or all 1 bits
1477
1478         if Compile_Time_Known_Value (Rhs) then
1479            Rhs_Val       := Expr_Rep_Value (Rhs);
1480            Rhs_Val_Known := True;
1481
1482         --  The following test catches the case of an unchecked conversion of
1483         --  an integer literal. This results from optimizing aggregates of
1484         --  packed types.
1485
1486         elsif Nkind (Rhs) = N_Unchecked_Type_Conversion
1487           and then Compile_Time_Known_Value (Expression (Rhs))
1488         then
1489            Rhs_Val       := Expr_Rep_Value (Expression (Rhs));
1490            Rhs_Val_Known := True;
1491
1492         else
1493            Rhs_Val       := No_Uint;
1494            Rhs_Val_Known := False;
1495         end if;
1496
1497         --  Some special checks for the case where the right hand value is
1498         --  known at compile time. Basically we have to take care of the
1499         --  implicit conversion to the subtype of the component object.
1500
1501         if Rhs_Val_Known then
1502
1503            --  If we have a biased component type then we must manually do the
1504            --  biasing, since we are taking responsibility in this case for
1505            --  constructing the exact bit pattern to be used.
1506
1507            if Has_Biased_Representation (Ctyp) then
1508               Rhs_Val := Rhs_Val - Expr_Rep_Value (Type_Low_Bound (Ctyp));
1509            end if;
1510
1511            --  For a negative value, we manually convert the two's complement
1512            --  value to a corresponding unsigned value, so that the proper
1513            --  field width is maintained. If we did not do this, we would
1514            --  get too many leading sign bits later on.
1515
1516            if Rhs_Val < 0 then
1517               Rhs_Val := 2 ** UI_From_Int (Csiz) + Rhs_Val;
1518            end if;
1519         end if;
1520
1521         --  Now create copies removing side effects. Note that in some complex
1522         --  cases, this may cause the fact that we have already set a packed
1523         --  array type on Obj to get lost. So we save the type of Obj, and
1524         --  make sure it is reset properly.
1525
1526         declare
1527            T : constant Entity_Id := Etype (Obj);
1528         begin
1529            New_Lhs := Duplicate_Subexpr (Obj, True);
1530            New_Rhs := Duplicate_Subexpr_No_Checks (Obj);
1531            Set_Etype (Obj, T);
1532            Set_Etype (New_Lhs, T);
1533            Set_Etype (New_Rhs, T);
1534
1535            if Reverse_Storage_Order (Base_Type (Atyp))
1536              and then Esize (T) > 8
1537              and then not In_Reverse_Storage_Order_Object (Obj)
1538            then
1539               Require_Byte_Swapping := True;
1540               New_Rhs := Byte_Swap (New_Rhs);
1541            end if;
1542         end;
1543
1544         --  First we deal with the "and"
1545
1546         if not Rhs_Val_Known or else Rhs_Val /= Cmask then
1547            declare
1548               Mask1 : Node_Id;
1549               Lit   : Node_Id;
1550
1551            begin
1552               if Compile_Time_Known_Value (Shift) then
1553                  Mask1 :=
1554                    Make_Integer_Literal (Loc,
1555                      Modulus (Etype (Obj)) - 1 -
1556                                 (Cmask * (2 ** Expr_Value (Get_Shift))));
1557                  Set_Print_In_Hex (Mask1);
1558
1559               else
1560                  Lit := Make_Integer_Literal (Loc, Cmask);
1561                  Set_Print_In_Hex (Lit);
1562                  Mask1 :=
1563                    Make_Op_Not (Loc,
1564                      Right_Opnd => Make_Shift_Left (Lit, Get_Shift));
1565               end if;
1566
1567               New_Rhs :=
1568                 Make_Op_And (Loc,
1569                   Left_Opnd  => New_Rhs,
1570                   Right_Opnd => Mask1);
1571            end;
1572         end if;
1573
1574         --  Then deal with the "or"
1575
1576         if not Rhs_Val_Known or else Rhs_Val /= 0 then
1577            declare
1578               Or_Rhs : Node_Id;
1579
1580               procedure Fixup_Rhs;
1581               --  Adjust Rhs by bias if biased representation for components
1582               --  or remove extraneous high order sign bits if signed.
1583
1584               procedure Fixup_Rhs is
1585                  Etyp : constant Entity_Id := Etype (Rhs);
1586
1587               begin
1588                  --  For biased case, do the required biasing by simply
1589                  --  converting to the biased subtype (the conversion
1590                  --  will generate the required bias).
1591
1592                  if Has_Biased_Representation (Ctyp) then
1593                     Rhs := Convert_To (Ctyp, Rhs);
1594
1595                  --  For a signed integer type that is not biased, generate
1596                  --  a conversion to unsigned to strip high order sign bits.
1597
1598                  elsif Is_Signed_Integer_Type (Ctyp) then
1599                     Rhs := Unchecked_Convert_To (RTE (Bits_Id (Csiz)), Rhs);
1600                  end if;
1601
1602                  --  Set Etype, since it can be referenced before the node is
1603                  --  completely analyzed.
1604
1605                  Set_Etype (Rhs, Etyp);
1606
1607                  --  We now need to do an unchecked conversion of the
1608                  --  result to the target type, but it is important that
1609                  --  this conversion be a right justified conversion and
1610                  --  not a left justified conversion.
1611
1612                  Rhs := RJ_Unchecked_Convert_To (Etype (Obj), Rhs);
1613
1614               end Fixup_Rhs;
1615
1616            begin
1617               if Rhs_Val_Known
1618                 and then Compile_Time_Known_Value (Get_Shift)
1619               then
1620                  Or_Rhs :=
1621                    Make_Integer_Literal (Loc,
1622                      Rhs_Val * (2 ** Expr_Value (Get_Shift)));
1623                  Set_Print_In_Hex (Or_Rhs);
1624
1625               else
1626                  --  We have to convert the right hand side to Etype (Obj).
1627                  --  A special case arises if what we have now is a Val
1628                  --  attribute reference whose expression type is Etype (Obj).
1629                  --  This happens for assignments of fields from the same
1630                  --  array. In this case we get the required right hand side
1631                  --  by simply removing the inner attribute reference.
1632
1633                  if Nkind (Rhs) = N_Attribute_Reference
1634                    and then Attribute_Name (Rhs) = Name_Val
1635                    and then Etype (First (Expressions (Rhs))) = Etype (Obj)
1636                  then
1637                     Rhs := Relocate_Node (First (Expressions (Rhs)));
1638                     Fixup_Rhs;
1639
1640                  --  If the value of the right hand side is a known integer
1641                  --  value, then just replace it by an untyped constant,
1642                  --  which will be properly retyped when we analyze and
1643                  --  resolve the expression.
1644
1645                  elsif Rhs_Val_Known then
1646
1647                     --  Note that Rhs_Val has already been normalized to
1648                     --  be an unsigned value with the proper number of bits.
1649
1650                     Rhs := Make_Integer_Literal (Loc, Rhs_Val);
1651
1652                  --  Otherwise we need an unchecked conversion
1653
1654                  else
1655                     Fixup_Rhs;
1656                  end if;
1657
1658                  Or_Rhs := Make_Shift_Left (Rhs, Get_Shift);
1659               end if;
1660
1661               if Nkind (New_Rhs) = N_Op_And then
1662                  Set_Paren_Count (New_Rhs, 1);
1663               end if;
1664
1665               New_Rhs :=
1666                 Make_Op_Or (Loc,
1667                   Left_Opnd  => New_Rhs,
1668                   Right_Opnd => Or_Rhs);
1669            end;
1670         end if;
1671
1672         if Require_Byte_Swapping then
1673            Set_Etype (New_Rhs, Etype (Obj));
1674            New_Rhs := Byte_Swap (New_Rhs);
1675         end if;
1676
1677         --  Now do the rewrite
1678
1679         Rewrite (N,
1680           Make_Assignment_Statement (Loc,
1681             Name       => New_Lhs,
1682             Expression =>
1683               Unchecked_Convert_To (Etype (New_Lhs), New_Rhs)));
1684         Set_Assignment_OK (Name (N), Ass_OK);
1685
1686      --  All other component sizes for non-modular case
1687
1688      else
1689         --  We generate
1690
1691         --    Set_nn (Arr'address, Subscr, Bits_nn!(Rhs))
1692
1693         --  where Subscr is the computed linear subscript
1694
1695         declare
1696            Bits_nn : constant Entity_Id := RTE (Bits_Id (Csiz));
1697            Set_nn  : Entity_Id;
1698            Subscr  : Node_Id;
1699            Atyp    : Entity_Id;
1700
1701         begin
1702            if No (Bits_nn) then
1703
1704               --  Error, most likely High_Integrity_Mode restriction
1705
1706               return;
1707            end if;
1708
1709            --  Acquire proper Set entity. We use the aligned or unaligned
1710            --  case as appropriate.
1711
1712            if Known_Aligned_Enough (Obj, Csiz) then
1713               Set_nn := RTE (Set_Id (Csiz));
1714            else
1715               Set_nn := RTE (SetU_Id (Csiz));
1716            end if;
1717
1718            --  Now generate the set reference
1719
1720            Obj := Relocate_Node (Prefix (Lhs));
1721            Convert_To_Actual_Subtype (Obj);
1722            Atyp := Etype (Obj);
1723            Compute_Linear_Subscript (Atyp, Lhs, Subscr);
1724
1725            --  Below we must make the assumption that Obj is
1726            --  at least byte aligned, since otherwise its address
1727            --  cannot be taken. The assumption holds since the
1728            --  only arrays that can be misaligned are small packed
1729            --  arrays which are implemented as a modular type, and
1730            --  that is not the case here.
1731
1732            Rewrite (N,
1733              Make_Procedure_Call_Statement (Loc,
1734                  Name => New_Occurrence_Of (Set_nn, Loc),
1735                  Parameter_Associations => New_List (
1736                    Make_Attribute_Reference (Loc,
1737                      Prefix         => Obj,
1738                      Attribute_Name => Name_Address),
1739                    Subscr,
1740                    Unchecked_Convert_To (Bits_nn,
1741                      Convert_To (Ctyp, Rhs)))));
1742
1743         end;
1744      end if;
1745
1746      Analyze (N, Suppress => All_Checks);
1747   end Expand_Bit_Packed_Element_Set;
1748
1749   -------------------------------------
1750   -- Expand_Packed_Address_Reference --
1751   -------------------------------------
1752
1753   procedure Expand_Packed_Address_Reference (N : Node_Id) is
1754      Loc    : constant Source_Ptr := Sloc (N);
1755      Base   : Node_Id;
1756      Offset : Node_Id;
1757
1758   begin
1759      --  We build an expression that has the form
1760
1761      --    outer_object'Address
1762      --      + (linear-subscript * component_size  for each array reference
1763      --      +  field'Bit_Position                 for each record field
1764      --      +  ...
1765      --      +  ...) / Storage_Unit;
1766
1767      Get_Base_And_Bit_Offset (Prefix (N), Base, Offset);
1768
1769      Rewrite (N,
1770        Unchecked_Convert_To (RTE (RE_Address),
1771          Make_Op_Add (Loc,
1772            Left_Opnd =>
1773              Unchecked_Convert_To (RTE (RE_Integer_Address),
1774                Make_Attribute_Reference (Loc,
1775                  Prefix         => Base,
1776                  Attribute_Name => Name_Address)),
1777
1778            Right_Opnd =>
1779              Unchecked_Convert_To (RTE (RE_Integer_Address),
1780                Make_Op_Divide (Loc,
1781                  Left_Opnd => Offset,
1782                  Right_Opnd =>
1783                    Make_Integer_Literal (Loc, System_Storage_Unit))))));
1784
1785      Analyze_And_Resolve (N, RTE (RE_Address));
1786   end Expand_Packed_Address_Reference;
1787
1788   ---------------------------------
1789   -- Expand_Packed_Bit_Reference --
1790   ---------------------------------
1791
1792   procedure Expand_Packed_Bit_Reference (N : Node_Id) is
1793      Loc    : constant Source_Ptr := Sloc (N);
1794      Base   : Node_Id;
1795      Offset : Node_Id;
1796
1797   begin
1798      --  We build an expression that has the form
1799
1800      --    (linear-subscript * component_size      for each array reference
1801      --      +  field'Bit_Position                 for each record field
1802      --      +  ...
1803      --      +  ...) mod Storage_Unit;
1804
1805      Get_Base_And_Bit_Offset (Prefix (N), Base, Offset);
1806
1807      Rewrite (N,
1808        Unchecked_Convert_To (Universal_Integer,
1809          Make_Op_Mod (Loc,
1810            Left_Opnd => Offset,
1811            Right_Opnd => Make_Integer_Literal (Loc, System_Storage_Unit))));
1812
1813      Analyze_And_Resolve (N, Universal_Integer);
1814   end Expand_Packed_Bit_Reference;
1815
1816   ------------------------------------
1817   -- Expand_Packed_Boolean_Operator --
1818   ------------------------------------
1819
1820   --  This routine expands "a op b" for the packed cases
1821
1822   procedure Expand_Packed_Boolean_Operator (N : Node_Id) is
1823      Loc : constant Source_Ptr := Sloc (N);
1824      Typ : constant Entity_Id  := Etype (N);
1825      L   : constant Node_Id    := Relocate_Node (Left_Opnd  (N));
1826      R   : constant Node_Id    := Relocate_Node (Right_Opnd (N));
1827
1828      Ltyp : Entity_Id;
1829      Rtyp : Entity_Id;
1830      PAT  : Entity_Id;
1831
1832   begin
1833      Convert_To_Actual_Subtype (L);
1834      Convert_To_Actual_Subtype (R);
1835
1836      Ensure_Defined (Etype (L), N);
1837      Ensure_Defined (Etype (R), N);
1838
1839      Apply_Length_Check (R, Etype (L));
1840
1841      Ltyp := Etype (L);
1842      Rtyp := Etype (R);
1843
1844      --  Deal with silly case of XOR where the subcomponent has a range
1845      --  True .. True where an exception must be raised.
1846
1847      if Nkind (N) = N_Op_Xor then
1848         Silly_Boolean_Array_Xor_Test (N, Rtyp);
1849      end if;
1850
1851      --  Now that that silliness is taken care of, get packed array type
1852
1853      Convert_To_PAT_Type (L);
1854      Convert_To_PAT_Type (R);
1855
1856      PAT := Etype (L);
1857
1858      --  For the modular case, we expand a op b into
1859
1860      --    rtyp!(pat!(a) op pat!(b))
1861
1862      --  where rtyp is the Etype of the left operand. Note that we do not
1863      --  convert to the base type, since this would be unconstrained, and
1864      --  hence not have a corresponding packed array type set.
1865
1866      --  Note that both operands must be modular for this code to be used
1867
1868      if Is_Modular_Integer_Type (PAT)
1869           and then
1870         Is_Modular_Integer_Type (Etype (R))
1871      then
1872         declare
1873            P : Node_Id;
1874
1875         begin
1876            if Nkind (N) = N_Op_And then
1877               P := Make_Op_And (Loc, L, R);
1878
1879            elsif Nkind (N) = N_Op_Or then
1880               P := Make_Op_Or  (Loc, L, R);
1881
1882            else -- Nkind (N) = N_Op_Xor
1883               P := Make_Op_Xor (Loc, L, R);
1884            end if;
1885
1886            Rewrite (N, Unchecked_Convert_To (Ltyp, P));
1887         end;
1888
1889      --  For the array case, we insert the actions
1890
1891      --    Result : Ltype;
1892
1893      --    System.Bit_Ops.Bit_And/Or/Xor
1894      --     (Left'Address,
1895      --      Ltype'Length * Ltype'Component_Size;
1896      --      Right'Address,
1897      --      Rtype'Length * Rtype'Component_Size
1898      --      Result'Address);
1899
1900      --  where Left and Right are the Packed_Bytes{1,2,4} operands and
1901      --  the second argument and fourth arguments are the lengths of the
1902      --  operands in bits. Then we replace the expression by a reference
1903      --  to Result.
1904
1905      --  Note that if we are mixing a modular and array operand, everything
1906      --  works fine, since we ensure that the modular representation has the
1907      --  same physical layout as the array representation (that's what the
1908      --  left justified modular stuff in the big-endian case is about).
1909
1910      else
1911         declare
1912            Result_Ent : constant Entity_Id := Make_Temporary (Loc, 'T');
1913            E_Id       : RE_Id;
1914
1915         begin
1916            if Nkind (N) = N_Op_And then
1917               E_Id := RE_Bit_And;
1918
1919            elsif Nkind (N) = N_Op_Or then
1920               E_Id := RE_Bit_Or;
1921
1922            else -- Nkind (N) = N_Op_Xor
1923               E_Id := RE_Bit_Xor;
1924            end if;
1925
1926            Insert_Actions (N, New_List (
1927
1928              Make_Object_Declaration (Loc,
1929                Defining_Identifier => Result_Ent,
1930                Object_Definition => New_Occurrence_Of (Ltyp, Loc)),
1931
1932              Make_Procedure_Call_Statement (Loc,
1933                Name => New_Occurrence_Of (RTE (E_Id), Loc),
1934                  Parameter_Associations => New_List (
1935
1936                    Make_Byte_Aligned_Attribute_Reference (Loc,
1937                      Prefix         => L,
1938                      Attribute_Name => Name_Address),
1939
1940                    Make_Op_Multiply (Loc,
1941                      Left_Opnd =>
1942                        Make_Attribute_Reference (Loc,
1943                          Prefix         =>
1944                            New_Occurrence_Of
1945                              (Etype (First_Index (Ltyp)), Loc),
1946                          Attribute_Name => Name_Range_Length),
1947
1948                      Right_Opnd =>
1949                        Make_Integer_Literal (Loc, Component_Size (Ltyp))),
1950
1951                    Make_Byte_Aligned_Attribute_Reference (Loc,
1952                      Prefix         => R,
1953                      Attribute_Name => Name_Address),
1954
1955                    Make_Op_Multiply (Loc,
1956                      Left_Opnd =>
1957                        Make_Attribute_Reference (Loc,
1958                          Prefix         =>
1959                            New_Occurrence_Of
1960                              (Etype (First_Index (Rtyp)), Loc),
1961                          Attribute_Name => Name_Range_Length),
1962
1963                      Right_Opnd =>
1964                        Make_Integer_Literal (Loc, Component_Size (Rtyp))),
1965
1966                    Make_Byte_Aligned_Attribute_Reference (Loc,
1967                      Prefix => New_Occurrence_Of (Result_Ent, Loc),
1968                      Attribute_Name => Name_Address)))));
1969
1970            Rewrite (N,
1971              New_Occurrence_Of (Result_Ent, Loc));
1972         end;
1973      end if;
1974
1975      Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
1976   end Expand_Packed_Boolean_Operator;
1977
1978   -------------------------------------
1979   -- Expand_Packed_Element_Reference --
1980   -------------------------------------
1981
1982   procedure Expand_Packed_Element_Reference (N : Node_Id) is
1983      Loc   : constant Source_Ptr := Sloc (N);
1984      Obj   : Node_Id;
1985      Atyp  : Entity_Id;
1986      PAT   : Entity_Id;
1987      Ctyp  : Entity_Id;
1988      Csiz  : Int;
1989      Shift : Node_Id;
1990      Cmask : Uint;
1991      Lit   : Node_Id;
1992      Arg   : Node_Id;
1993
1994   begin
1995      --  If not bit packed, we have the enumeration case, which is easily
1996      --  dealt with (just adjust the subscripts of the indexed component)
1997
1998      --  Note: this leaves the result as an indexed component, which is
1999      --  still a variable, so can be used in the assignment case, as is
2000      --  required in the enumeration case.
2001
2002      if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
2003         Setup_Enumeration_Packed_Array_Reference (N);
2004         return;
2005      end if;
2006
2007      --  Remaining processing is for the bit-packed case
2008
2009      Obj := Relocate_Node (Prefix (N));
2010      Convert_To_Actual_Subtype (Obj);
2011      Atyp := Etype (Obj);
2012      PAT  := Packed_Array_Type (Atyp);
2013      Ctyp := Component_Type (Atyp);
2014      Csiz := UI_To_Int (Component_Size (Atyp));
2015
2016      --  For the AAMP target, indexing of certain packed array is passed
2017      --  through to the back end without expansion, because the expansion
2018      --  results in very inefficient code on that target. This allows the
2019      --  GNAAMP back end to generate specialized macros that support more
2020      --  efficient indexing of packed arrays with components having sizes
2021      --  that are small powers of two.
2022
2023      if AAMP_On_Target
2024        and then (Csiz = 1 or else Csiz = 2 or else Csiz = 4)
2025      then
2026         return;
2027      end if;
2028
2029      --  Case of component size 1,2,4 or any component size for the modular
2030      --  case. These are the cases for which we can inline the code.
2031
2032      if Csiz = 1 or else Csiz = 2 or else Csiz = 4
2033        or else (Present (PAT) and then Is_Modular_Integer_Type (PAT))
2034      then
2035         Setup_Inline_Packed_Array_Reference (N, Atyp, Obj, Cmask, Shift);
2036         Lit := Make_Integer_Literal (Loc, Cmask);
2037         Set_Print_In_Hex (Lit);
2038
2039         --  Byte swapping required for the Reverse_Storage_Order case, but
2040         --  only for a free-standing object (see note on Require_Byte_Swapping
2041         --  in Expand_Bit_Packed_Element_Set).
2042
2043         if Reverse_Storage_Order (Atyp)
2044           and then Esize (Atyp) > 8
2045           and then not In_Reverse_Storage_Order_Object (Obj)
2046         then
2047            Obj := Byte_Swap (Obj);
2048         end if;
2049
2050         --  We generate a shift right to position the field, followed by a
2051         --  masking operation to extract the bit field, and we finally do an
2052         --  unchecked conversion to convert the result to the required target.
2053
2054         --  Note that the unchecked conversion automatically deals with the
2055         --  bias if we are dealing with a biased representation. What will
2056         --  happen is that we temporarily generate the biased representation,
2057         --  but almost immediately that will be converted to the original
2058         --  unbiased component type, and the bias will disappear.
2059
2060         Arg :=
2061           Make_Op_And (Loc,
2062             Left_Opnd  => Make_Shift_Right (Obj, Shift),
2063             Right_Opnd => Lit);
2064
2065         --  We needed to analyze this before we do the unchecked convert
2066         --  below, but we need it temporarily attached to the tree for
2067         --  this analysis (hence the temporary Set_Parent call).
2068
2069         Set_Parent (Arg, Parent (N));
2070         Analyze_And_Resolve (Arg);
2071
2072         Rewrite (N, RJ_Unchecked_Convert_To (Ctyp, Arg));
2073
2074      --  All other component sizes for non-modular case
2075
2076      else
2077         --  We generate
2078
2079         --    Component_Type!(Get_nn (Arr'address, Subscr))
2080
2081         --  where Subscr is the computed linear subscript
2082
2083         declare
2084            Get_nn : Entity_Id;
2085            Subscr : Node_Id;
2086
2087         begin
2088            --  Acquire proper Get entity. We use the aligned or unaligned
2089            --  case as appropriate.
2090
2091            if Known_Aligned_Enough (Obj, Csiz) then
2092               Get_nn := RTE (Get_Id (Csiz));
2093            else
2094               Get_nn := RTE (GetU_Id (Csiz));
2095            end if;
2096
2097            --  Now generate the get reference
2098
2099            Compute_Linear_Subscript (Atyp, N, Subscr);
2100
2101            --  Below we make the assumption that Obj is at least byte
2102            --  aligned, since otherwise its address cannot be taken.
2103            --  The assumption holds since the only arrays that can be
2104            --  misaligned are small packed arrays which are implemented
2105            --  as a modular type, and that is not the case here.
2106
2107            Rewrite (N,
2108              Unchecked_Convert_To (Ctyp,
2109                Make_Function_Call (Loc,
2110                  Name => New_Occurrence_Of (Get_nn, Loc),
2111                  Parameter_Associations => New_List (
2112                    Make_Attribute_Reference (Loc,
2113                      Prefix         => Obj,
2114                      Attribute_Name => Name_Address),
2115                    Subscr))));
2116         end;
2117      end if;
2118
2119      Analyze_And_Resolve (N, Ctyp, Suppress => All_Checks);
2120
2121   end Expand_Packed_Element_Reference;
2122
2123   ----------------------
2124   -- Expand_Packed_Eq --
2125   ----------------------
2126
2127   --  Handles expansion of "=" on packed array types
2128
2129   procedure Expand_Packed_Eq (N : Node_Id) is
2130      Loc : constant Source_Ptr := Sloc (N);
2131      L   : constant Node_Id    := Relocate_Node (Left_Opnd  (N));
2132      R   : constant Node_Id    := Relocate_Node (Right_Opnd (N));
2133
2134      LLexpr : Node_Id;
2135      RLexpr : Node_Id;
2136
2137      Ltyp : Entity_Id;
2138      Rtyp : Entity_Id;
2139      PAT  : Entity_Id;
2140
2141   begin
2142      Convert_To_Actual_Subtype (L);
2143      Convert_To_Actual_Subtype (R);
2144      Ltyp := Underlying_Type (Etype (L));
2145      Rtyp := Underlying_Type (Etype (R));
2146
2147      Convert_To_PAT_Type (L);
2148      Convert_To_PAT_Type (R);
2149      PAT := Etype (L);
2150
2151      LLexpr :=
2152        Make_Op_Multiply (Loc,
2153          Left_Opnd =>
2154            Make_Attribute_Reference (Loc,
2155              Prefix         => New_Occurrence_Of (Ltyp, Loc),
2156              Attribute_Name => Name_Length),
2157          Right_Opnd =>
2158            Make_Integer_Literal (Loc, Component_Size (Ltyp)));
2159
2160      RLexpr :=
2161        Make_Op_Multiply (Loc,
2162          Left_Opnd =>
2163            Make_Attribute_Reference (Loc,
2164              Prefix         => New_Occurrence_Of (Rtyp, Loc),
2165              Attribute_Name => Name_Length),
2166          Right_Opnd =>
2167            Make_Integer_Literal (Loc, Component_Size (Rtyp)));
2168
2169      --  For the modular case, we transform the comparison to:
2170
2171      --    Ltyp'Length = Rtyp'Length and then PAT!(L) = PAT!(R)
2172
2173      --  where PAT is the packed array type. This works fine, since in the
2174      --  modular case we guarantee that the unused bits are always zeroes.
2175      --  We do have to compare the lengths because we could be comparing
2176      --  two different subtypes of the same base type.
2177
2178      if Is_Modular_Integer_Type (PAT) then
2179         Rewrite (N,
2180           Make_And_Then (Loc,
2181             Left_Opnd =>
2182               Make_Op_Eq (Loc,
2183                 Left_Opnd  => LLexpr,
2184                 Right_Opnd => RLexpr),
2185
2186             Right_Opnd =>
2187               Make_Op_Eq (Loc,
2188                 Left_Opnd => L,
2189                 Right_Opnd => R)));
2190
2191      --  For the non-modular case, we call a runtime routine
2192
2193      --    System.Bit_Ops.Bit_Eq
2194      --      (L'Address, L_Length, R'Address, R_Length)
2195
2196      --  where PAT is the packed array type, and the lengths are the lengths
2197      --  in bits of the original packed arrays. This routine takes care of
2198      --  not comparing the unused bits in the last byte.
2199
2200      else
2201         Rewrite (N,
2202           Make_Function_Call (Loc,
2203             Name => New_Occurrence_Of (RTE (RE_Bit_Eq), Loc),
2204             Parameter_Associations => New_List (
2205               Make_Byte_Aligned_Attribute_Reference (Loc,
2206                 Prefix         => L,
2207                 Attribute_Name => Name_Address),
2208
2209               LLexpr,
2210
2211               Make_Byte_Aligned_Attribute_Reference (Loc,
2212                 Prefix         => R,
2213                 Attribute_Name => Name_Address),
2214
2215               RLexpr)));
2216      end if;
2217
2218      Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
2219   end Expand_Packed_Eq;
2220
2221   -----------------------
2222   -- Expand_Packed_Not --
2223   -----------------------
2224
2225   --  Handles expansion of "not" on packed array types
2226
2227   procedure Expand_Packed_Not (N : Node_Id) is
2228      Loc  : constant Source_Ptr := Sloc (N);
2229      Typ  : constant Entity_Id  := Etype (N);
2230      Opnd : constant Node_Id    := Relocate_Node (Right_Opnd (N));
2231
2232      Rtyp : Entity_Id;
2233      PAT  : Entity_Id;
2234      Lit  : Node_Id;
2235
2236   begin
2237      Convert_To_Actual_Subtype (Opnd);
2238      Rtyp := Etype (Opnd);
2239
2240      --  Deal with silly False..False and True..True subtype case
2241
2242      Silly_Boolean_Array_Not_Test (N, Rtyp);
2243
2244      --  Now that the silliness is taken care of, get packed array type
2245
2246      Convert_To_PAT_Type (Opnd);
2247      PAT := Etype (Opnd);
2248
2249      --  For the case where the packed array type is a modular type, "not A"
2250      --  expands simply into:
2251
2252      --     Rtyp!(PAT!(A) xor Mask)
2253
2254      --  where PAT is the packed array type, Mask is a mask of all 1 bits of
2255      --  length equal to the size of this packed type, and Rtyp is the actual
2256      --  actual subtype of the operand.
2257
2258      Lit := Make_Integer_Literal (Loc, 2 ** RM_Size (PAT) - 1);
2259      Set_Print_In_Hex (Lit);
2260
2261      if not Is_Array_Type (PAT) then
2262         Rewrite (N,
2263           Unchecked_Convert_To (Rtyp,
2264             Make_Op_Xor (Loc,
2265               Left_Opnd  => Opnd,
2266               Right_Opnd => Lit)));
2267
2268      --  For the array case, we insert the actions
2269
2270      --    Result : Typ;
2271
2272      --    System.Bit_Ops.Bit_Not
2273      --     (Opnd'Address,
2274      --      Typ'Length * Typ'Component_Size,
2275      --      Result'Address);
2276
2277      --  where Opnd is the Packed_Bytes{1,2,4} operand and the second argument
2278      --  is the length of the operand in bits. We then replace the expression
2279      --  with a reference to Result.
2280
2281      else
2282         declare
2283            Result_Ent : constant Entity_Id := Make_Temporary (Loc, 'T');
2284
2285         begin
2286            Insert_Actions (N, New_List (
2287              Make_Object_Declaration (Loc,
2288                Defining_Identifier => Result_Ent,
2289                Object_Definition   => New_Occurrence_Of (Rtyp, Loc)),
2290
2291              Make_Procedure_Call_Statement (Loc,
2292                Name => New_Occurrence_Of (RTE (RE_Bit_Not), Loc),
2293                  Parameter_Associations => New_List (
2294                    Make_Byte_Aligned_Attribute_Reference (Loc,
2295                      Prefix         => Opnd,
2296                      Attribute_Name => Name_Address),
2297
2298                    Make_Op_Multiply (Loc,
2299                      Left_Opnd =>
2300                        Make_Attribute_Reference (Loc,
2301                          Prefix         =>
2302                            New_Occurrence_Of
2303                              (Etype (First_Index (Rtyp)), Loc),
2304                          Attribute_Name => Name_Range_Length),
2305
2306                      Right_Opnd =>
2307                        Make_Integer_Literal (Loc, Component_Size (Rtyp))),
2308
2309                    Make_Byte_Aligned_Attribute_Reference (Loc,
2310                      Prefix         => New_Occurrence_Of (Result_Ent, Loc),
2311                      Attribute_Name => Name_Address)))));
2312
2313            Rewrite (N, New_Occurrence_Of (Result_Ent, Loc));
2314         end;
2315      end if;
2316
2317      Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
2318   end Expand_Packed_Not;
2319
2320   -----------------------------
2321   -- Get_Base_And_Bit_Offset --
2322   -----------------------------
2323
2324   procedure Get_Base_And_Bit_Offset
2325     (N      : Node_Id;
2326      Base   : out Node_Id;
2327      Offset : out Node_Id)
2328   is
2329      Loc    : Source_Ptr;
2330      Term   : Node_Id;
2331      Atyp   : Entity_Id;
2332      Subscr : Node_Id;
2333
2334   begin
2335      Base   := N;
2336      Offset := Empty;
2337
2338      --  We build up an expression serially that has the form
2339
2340      --    linear-subscript * component_size       for each array reference
2341      --      +  field'Bit_Position                 for each record field
2342      --      +  ...
2343
2344      loop
2345         Loc := Sloc (Base);
2346
2347         if Nkind (Base) = N_Indexed_Component then
2348            Convert_To_Actual_Subtype (Prefix (Base));
2349            Atyp := Etype (Prefix (Base));
2350            Compute_Linear_Subscript (Atyp, Base, Subscr);
2351
2352            Term :=
2353              Make_Op_Multiply (Loc,
2354                Left_Opnd => Subscr,
2355                Right_Opnd =>
2356                 Make_Attribute_Reference (Loc,
2357                   Prefix         => New_Occurrence_Of (Atyp, Loc),
2358                   Attribute_Name => Name_Component_Size));
2359
2360         elsif Nkind (Base) = N_Selected_Component then
2361            Term :=
2362              Make_Attribute_Reference (Loc,
2363                Prefix         => Selector_Name (Base),
2364                Attribute_Name => Name_Bit_Position);
2365
2366         else
2367            return;
2368         end if;
2369
2370         if No (Offset) then
2371            Offset := Term;
2372
2373         else
2374            Offset :=
2375              Make_Op_Add (Loc,
2376                Left_Opnd  => Offset,
2377                Right_Opnd => Term);
2378         end if;
2379
2380         Base := Prefix (Base);
2381      end loop;
2382   end Get_Base_And_Bit_Offset;
2383
2384   -------------------------------------
2385   -- Involves_Packed_Array_Reference --
2386   -------------------------------------
2387
2388   function Involves_Packed_Array_Reference (N : Node_Id) return Boolean is
2389   begin
2390      if Nkind (N) = N_Indexed_Component
2391        and then Is_Bit_Packed_Array (Etype (Prefix (N)))
2392      then
2393         return True;
2394
2395      elsif Nkind (N) = N_Selected_Component then
2396         return Involves_Packed_Array_Reference (Prefix (N));
2397
2398      else
2399         return False;
2400      end if;
2401   end Involves_Packed_Array_Reference;
2402
2403   --------------------------
2404   -- Known_Aligned_Enough --
2405   --------------------------
2406
2407   function Known_Aligned_Enough (Obj : Node_Id; Csiz : Nat) return Boolean is
2408      Typ : constant Entity_Id := Etype (Obj);
2409
2410      function In_Partially_Packed_Record (Comp : Entity_Id) return Boolean;
2411      --  If the component is in a record that contains previous packed
2412      --  components, consider it unaligned because the back-end might
2413      --  choose to pack the rest of the record. Lead to less efficient code,
2414      --  but safer vis-a-vis of back-end choices.
2415
2416      --------------------------------
2417      -- In_Partially_Packed_Record --
2418      --------------------------------
2419
2420      function In_Partially_Packed_Record (Comp : Entity_Id) return Boolean is
2421         Rec_Type  : constant Entity_Id := Scope (Comp);
2422         Prev_Comp : Entity_Id;
2423
2424      begin
2425         Prev_Comp := First_Entity (Rec_Type);
2426         while Present (Prev_Comp) loop
2427            if Is_Packed (Etype (Prev_Comp)) then
2428               return True;
2429
2430            elsif Prev_Comp = Comp then
2431               return False;
2432            end if;
2433
2434            Next_Entity (Prev_Comp);
2435         end loop;
2436
2437         return False;
2438      end  In_Partially_Packed_Record;
2439
2440   --  Start of processing for Known_Aligned_Enough
2441
2442   begin
2443      --  Odd bit sizes don't need alignment anyway
2444
2445      if Csiz mod 2 = 1 then
2446         return True;
2447
2448      --  If we have a specified alignment, see if it is sufficient, if not
2449      --  then we can't possibly be aligned enough in any case.
2450
2451      elsif Known_Alignment (Etype (Obj)) then
2452         --  Alignment required is 4 if size is a multiple of 4, and
2453         --  2 otherwise (e.g. 12 bits requires 4, 10 bits requires 2)
2454
2455         if Alignment (Etype (Obj)) < 4 - (Csiz mod 4) then
2456            return False;
2457         end if;
2458      end if;
2459
2460      --  OK, alignment should be sufficient, if object is aligned
2461
2462      --  If object is strictly aligned, then it is definitely aligned
2463
2464      if Strict_Alignment (Typ) then
2465         return True;
2466
2467      --  Case of subscripted array reference
2468
2469      elsif Nkind (Obj) = N_Indexed_Component then
2470
2471         --  If we have a pointer to an array, then this is definitely
2472         --  aligned, because pointers always point to aligned versions.
2473
2474         if Is_Access_Type (Etype (Prefix (Obj))) then
2475            return True;
2476
2477         --  Otherwise, go look at the prefix
2478
2479         else
2480            return Known_Aligned_Enough (Prefix (Obj), Csiz);
2481         end if;
2482
2483      --  Case of record field
2484
2485      elsif Nkind (Obj) = N_Selected_Component then
2486
2487         --  What is significant here is whether the record type is packed
2488
2489         if Is_Record_Type (Etype (Prefix (Obj)))
2490           and then Is_Packed (Etype (Prefix (Obj)))
2491         then
2492            return False;
2493
2494         --  Or the component has a component clause which might cause
2495         --  the component to become unaligned (we can't tell if the
2496         --  backend is doing alignment computations).
2497
2498         elsif Present (Component_Clause (Entity (Selector_Name (Obj)))) then
2499            return False;
2500
2501         elsif In_Partially_Packed_Record (Entity (Selector_Name (Obj))) then
2502            return False;
2503
2504         --  In all other cases, go look at prefix
2505
2506         else
2507            return Known_Aligned_Enough (Prefix (Obj), Csiz);
2508         end if;
2509
2510      elsif Nkind (Obj) = N_Type_Conversion then
2511         return Known_Aligned_Enough (Expression (Obj), Csiz);
2512
2513      --  For a formal parameter, it is safer to assume that it is not
2514      --  aligned, because the formal may be unconstrained while the actual
2515      --  is constrained. In this situation, a small constrained packed
2516      --  array, represented in modular form, may be unaligned.
2517
2518      elsif Is_Entity_Name (Obj) then
2519         return not Is_Formal (Entity (Obj));
2520      else
2521
2522      --  If none of the above, must be aligned
2523         return True;
2524      end if;
2525   end Known_Aligned_Enough;
2526
2527   ---------------------
2528   -- Make_Shift_Left --
2529   ---------------------
2530
2531   function Make_Shift_Left (N : Node_Id; S : Node_Id) return Node_Id is
2532      Nod : Node_Id;
2533
2534   begin
2535      if Compile_Time_Known_Value (S) and then Expr_Value (S) = 0 then
2536         return N;
2537      else
2538         Nod :=
2539           Make_Op_Shift_Left (Sloc (N),
2540             Left_Opnd  => N,
2541             Right_Opnd => S);
2542         Set_Shift_Count_OK (Nod, True);
2543         return Nod;
2544      end if;
2545   end Make_Shift_Left;
2546
2547   ----------------------
2548   -- Make_Shift_Right --
2549   ----------------------
2550
2551   function Make_Shift_Right (N : Node_Id; S : Node_Id) return Node_Id is
2552      Nod : Node_Id;
2553
2554   begin
2555      if Compile_Time_Known_Value (S) and then Expr_Value (S) = 0 then
2556         return N;
2557      else
2558         Nod :=
2559           Make_Op_Shift_Right (Sloc (N),
2560             Left_Opnd  => N,
2561             Right_Opnd => S);
2562         Set_Shift_Count_OK (Nod, True);
2563         return Nod;
2564      end if;
2565   end Make_Shift_Right;
2566
2567   -----------------------------
2568   -- RJ_Unchecked_Convert_To --
2569   -----------------------------
2570
2571   function RJ_Unchecked_Convert_To
2572     (Typ  : Entity_Id;
2573      Expr : Node_Id) return Node_Id
2574   is
2575      Source_Typ : constant Entity_Id := Etype (Expr);
2576      Target_Typ : constant Entity_Id := Typ;
2577
2578      Src : Node_Id := Expr;
2579
2580      Source_Siz : Nat;
2581      Target_Siz : Nat;
2582
2583   begin
2584      Source_Siz := UI_To_Int (RM_Size (Source_Typ));
2585      Target_Siz := UI_To_Int (RM_Size (Target_Typ));
2586
2587      --  First step, if the source type is not a discrete type, then we first
2588      --  convert to a modular type of the source length, since otherwise, on
2589      --  a big-endian machine, we get left-justification. We do it for little-
2590      --  endian machines as well, because there might be junk bits that are
2591      --  not cleared if the type is not numeric.
2592
2593      if Source_Siz /= Target_Siz
2594        and then not Is_Discrete_Type (Source_Typ)
2595      then
2596         Src := Unchecked_Convert_To (RTE (Bits_Id (Source_Siz)), Src);
2597      end if;
2598
2599      --  In the big endian case, if the lengths of the two types differ, then
2600      --  we must worry about possible left justification in the conversion,
2601      --  and avoiding that is what this is all about.
2602
2603      if Bytes_Big_Endian and then Source_Siz /= Target_Siz then
2604
2605         --  Next step. If the target is not a discrete type, then we first
2606         --  convert to a modular type of the target length, since otherwise,
2607         --  on a big-endian machine, we get left-justification.
2608
2609         if not Is_Discrete_Type (Target_Typ) then
2610            Src := Unchecked_Convert_To (RTE (Bits_Id (Target_Siz)), Src);
2611         end if;
2612      end if;
2613
2614      --  And now we can do the final conversion to the target type
2615
2616      return Unchecked_Convert_To (Target_Typ, Src);
2617   end RJ_Unchecked_Convert_To;
2618
2619   ----------------------------------------------
2620   -- Setup_Enumeration_Packed_Array_Reference --
2621   ----------------------------------------------
2622
2623   --  All we have to do here is to find the subscripts that correspond to the
2624   --  index positions that have non-standard enumeration types and insert a
2625   --  Pos attribute to get the proper subscript value.
2626
2627   --  Finally the prefix must be uncheck-converted to the corresponding packed
2628   --  array type.
2629
2630   --  Note that the component type is unchanged, so we do not need to fiddle
2631   --  with the types (Gigi always automatically takes the packed array type if
2632   --  it is set, as it will be in this case).
2633
2634   procedure Setup_Enumeration_Packed_Array_Reference (N : Node_Id) is
2635      Pfx   : constant Node_Id   := Prefix (N);
2636      Typ   : constant Entity_Id := Etype (N);
2637      Exprs : constant List_Id   := Expressions (N);
2638      Expr  : Node_Id;
2639
2640   begin
2641      --  If the array is unconstrained, then we replace the array reference
2642      --  with its actual subtype. This actual subtype will have a packed array
2643      --  type with appropriate bounds.
2644
2645      if not Is_Constrained (Packed_Array_Type (Etype (Pfx))) then
2646         Convert_To_Actual_Subtype (Pfx);
2647      end if;
2648
2649      Expr := First (Exprs);
2650      while Present (Expr) loop
2651         declare
2652            Loc      : constant Source_Ptr := Sloc (Expr);
2653            Expr_Typ : constant Entity_Id := Etype (Expr);
2654
2655         begin
2656            if Is_Enumeration_Type (Expr_Typ)
2657              and then Has_Non_Standard_Rep (Expr_Typ)
2658            then
2659               Rewrite (Expr,
2660                 Make_Attribute_Reference (Loc,
2661                   Prefix         => New_Occurrence_Of (Expr_Typ, Loc),
2662                   Attribute_Name => Name_Pos,
2663                   Expressions    => New_List (Relocate_Node (Expr))));
2664               Analyze_And_Resolve (Expr, Standard_Natural);
2665            end if;
2666         end;
2667
2668         Next (Expr);
2669      end loop;
2670
2671      Rewrite (N,
2672        Make_Indexed_Component (Sloc (N),
2673          Prefix      =>
2674            Unchecked_Convert_To (Packed_Array_Type (Etype (Pfx)), Pfx),
2675          Expressions => Exprs));
2676
2677      Analyze_And_Resolve (N, Typ);
2678   end Setup_Enumeration_Packed_Array_Reference;
2679
2680   -----------------------------------------
2681   -- Setup_Inline_Packed_Array_Reference --
2682   -----------------------------------------
2683
2684   procedure Setup_Inline_Packed_Array_Reference
2685     (N      : Node_Id;
2686      Atyp   : Entity_Id;
2687      Obj    : in out Node_Id;
2688      Cmask  : out Uint;
2689      Shift  : out Node_Id)
2690   is
2691      Loc  : constant Source_Ptr := Sloc (N);
2692      PAT  : Entity_Id;
2693      Otyp : Entity_Id;
2694      Csiz : Uint;
2695      Osiz : Uint;
2696
2697   begin
2698      Csiz := Component_Size (Atyp);
2699
2700      Convert_To_PAT_Type (Obj);
2701      PAT := Etype (Obj);
2702
2703      Cmask := 2 ** Csiz - 1;
2704
2705      if Is_Array_Type (PAT) then
2706         Otyp := Component_Type (PAT);
2707         Osiz := Component_Size (PAT);
2708
2709      else
2710         Otyp := PAT;
2711
2712         --  In the case where the PAT is a modular type, we want the actual
2713         --  size in bits of the modular value we use. This is neither the
2714         --  Object_Size nor the Value_Size, either of which may have been
2715         --  reset to strange values, but rather the minimum size. Note that
2716         --  since this is a modular type with full range, the issue of
2717         --  biased representation does not arise.
2718
2719         Osiz := UI_From_Int (Minimum_Size (Otyp));
2720      end if;
2721
2722      Compute_Linear_Subscript (Atyp, N, Shift);
2723
2724      --  If the component size is not 1, then the subscript must be multiplied
2725      --  by the component size to get the shift count.
2726
2727      if Csiz /= 1 then
2728         Shift :=
2729           Make_Op_Multiply (Loc,
2730             Left_Opnd  => Make_Integer_Literal (Loc, Csiz),
2731             Right_Opnd => Shift);
2732      end if;
2733
2734      --  If we have the array case, then this shift count must be broken down
2735      --  into a byte subscript, and a shift within the byte.
2736
2737      if Is_Array_Type (PAT) then
2738
2739         declare
2740            New_Shift : Node_Id;
2741
2742         begin
2743            --  We must analyze shift, since we will duplicate it
2744
2745            Set_Parent (Shift, N);
2746            Analyze_And_Resolve
2747              (Shift, Standard_Integer, Suppress => All_Checks);
2748
2749            --  The shift count within the word is
2750            --    shift mod Osiz
2751
2752            New_Shift :=
2753              Make_Op_Mod (Loc,
2754                Left_Opnd  => Duplicate_Subexpr (Shift),
2755                Right_Opnd => Make_Integer_Literal (Loc, Osiz));
2756
2757            --  The subscript to be used on the PAT array is
2758            --    shift / Osiz
2759
2760            Obj :=
2761              Make_Indexed_Component (Loc,
2762                Prefix => Obj,
2763                Expressions => New_List (
2764                  Make_Op_Divide (Loc,
2765                    Left_Opnd  => Duplicate_Subexpr (Shift),
2766                    Right_Opnd => Make_Integer_Literal (Loc, Osiz))));
2767
2768            Shift := New_Shift;
2769         end;
2770
2771      --  For the modular integer case, the object to be manipulated is the
2772      --  entire array, so Obj is unchanged. Note that we will reset its type
2773      --  to PAT before returning to the caller.
2774
2775      else
2776         null;
2777      end if;
2778
2779      --  The one remaining step is to modify the shift count for the
2780      --  big-endian case. Consider the following example in a byte:
2781
2782      --     xxxxxxxx  bits of byte
2783      --     vvvvvvvv  bits of value
2784      --     33221100  little-endian numbering
2785      --     00112233  big-endian numbering
2786
2787      --  Here we have the case of 2-bit fields
2788
2789      --  For the little-endian case, we already have the proper shift count
2790      --  set, e.g. for element 2, the shift count is 2*2 = 4.
2791
2792      --  For the big endian case, we have to adjust the shift count, computing
2793      --  it as (N - F) - Shift, where N is the number of bits in an element of
2794      --  the array used to implement the packed array, F is the number of bits
2795      --  in a source array element, and Shift is the count so far computed.
2796
2797      --  We also have to adjust if the storage order is reversed
2798
2799      if Bytes_Big_Endian xor Reverse_Storage_Order (Base_Type (Atyp)) then
2800         Shift :=
2801           Make_Op_Subtract (Loc,
2802             Left_Opnd  => Make_Integer_Literal (Loc, Osiz - Csiz),
2803             Right_Opnd => Shift);
2804      end if;
2805
2806      Set_Parent (Shift, N);
2807      Set_Parent (Obj, N);
2808      Analyze_And_Resolve (Obj,   Otyp,             Suppress => All_Checks);
2809      Analyze_And_Resolve (Shift, Standard_Integer, Suppress => All_Checks);
2810
2811      --  Make sure final type of object is the appropriate packed type
2812
2813      Set_Etype (Obj, Otyp);
2814
2815   end Setup_Inline_Packed_Array_Reference;
2816
2817end Exp_Pakd;
2818