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