OSDN Git Service

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