1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- S Y S T E M . A U X _ D E C -- 6-- -- 7-- B o d y -- 8-- -- 9-- Copyright (C) 1992-2019, Free Software Foundation, Inc. -- 10-- -- 11-- GNAT is free software; you can redistribute it and/Or modify it under -- 12-- terms of the GNU General Public License as published by the Free Soft- -- 13-- ware Foundation; either version 3, or (at your option) any later ver- -- 14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16-- or FITNESS FOR A PARTICULAR PURPOSE. -- 17-- -- 18-- As a special exception under Section 7 of GPL version 3, you are granted -- 19-- additional permissions described in the GCC Runtime Library Exception, -- 20-- version 3.1, as published by the Free Software Foundation. -- 21-- -- 22-- You should have received a copy of the GNU General Public License and -- 23-- a copy of the GCC Runtime Library Exception along with this program; -- 24-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- 25-- <http://www.gnu.org/licenses/>. -- 26-- -- 27-- GNAT was originally developed by the GNAT team at New York University. -- 28-- Extensive contributions were provided by Ada Core Technologies Inc. -- 29-- -- 30------------------------------------------------------------------------------ 31 32pragma Style_Checks (All_Checks); 33-- Turn off alpha ordering check on subprograms, this unit is laid 34-- out to correspond to the declarations in the DEC 83 System unit. 35 36with System.Soft_Links; 37 38package body System.Aux_DEC is 39 40 package SSL renames System.Soft_Links; 41 42 ----------------------------------- 43 -- Operations on Largest_Integer -- 44 ----------------------------------- 45 46 -- It would be nice to replace these with intrinsics, but that does 47 -- not work yet (the back end would be ok, but GNAT itself objects) 48 49 type LIU is mod 2 ** Largest_Integer'Size; 50 -- Unsigned type of same length as Largest_Integer 51 52 function To_LI is new Ada.Unchecked_Conversion (LIU, Largest_Integer); 53 function From_LI is new Ada.Unchecked_Conversion (Largest_Integer, LIU); 54 55 function "not" (Left : Largest_Integer) return Largest_Integer is 56 begin 57 return To_LI (not From_LI (Left)); 58 end "not"; 59 60 function "and" (Left, Right : Largest_Integer) return Largest_Integer is 61 begin 62 return To_LI (From_LI (Left) and From_LI (Right)); 63 end "and"; 64 65 function "or" (Left, Right : Largest_Integer) return Largest_Integer is 66 begin 67 return To_LI (From_LI (Left) or From_LI (Right)); 68 end "or"; 69 70 function "xor" (Left, Right : Largest_Integer) return Largest_Integer is 71 begin 72 return To_LI (From_LI (Left) xor From_LI (Right)); 73 end "xor"; 74 75 -------------------------------------- 76 -- Arithmetic Operations on Address -- 77 -------------------------------------- 78 79 -- It would be nice to replace these with intrinsics, but that does 80 -- not work yet (the back end would be ok, but GNAT itself objects) 81 82 Asiz : constant Integer := Integer (Address'Size) - 1; 83 84 type SA is range -(2 ** Asiz) .. 2 ** Asiz - 1; 85 -- Signed type of same size as Address 86 87 function To_A is new Ada.Unchecked_Conversion (SA, Address); 88 function From_A is new Ada.Unchecked_Conversion (Address, SA); 89 90 function "+" (Left : Address; Right : Integer) return Address is 91 begin 92 return To_A (From_A (Left) + SA (Right)); 93 end "+"; 94 95 function "+" (Left : Integer; Right : Address) return Address is 96 begin 97 return To_A (SA (Left) + From_A (Right)); 98 end "+"; 99 100 function "-" (Left : Address; Right : Address) return Integer is 101 pragma Unsuppress (All_Checks); 102 -- Because this can raise Constraint_Error for 64-bit addresses 103 begin 104 return Integer (From_A (Left) - From_A (Right)); 105 end "-"; 106 107 function "-" (Left : Address; Right : Integer) return Address is 108 begin 109 return To_A (From_A (Left) - SA (Right)); 110 end "-"; 111 112 ------------------------ 113 -- Fetch_From_Address -- 114 ------------------------ 115 116 function Fetch_From_Address (A : Address) return Target is 117 type T_Ptr is access all Target; 118 function To_T_Ptr is new Ada.Unchecked_Conversion (Address, T_Ptr); 119 Ptr : constant T_Ptr := To_T_Ptr (A); 120 begin 121 return Ptr.all; 122 end Fetch_From_Address; 123 124 ----------------------- 125 -- Assign_To_Address -- 126 ----------------------- 127 128 procedure Assign_To_Address (A : Address; T : Target) is 129 type T_Ptr is access all Target; 130 function To_T_Ptr is new Ada.Unchecked_Conversion (Address, T_Ptr); 131 Ptr : constant T_Ptr := To_T_Ptr (A); 132 begin 133 Ptr.all := T; 134 end Assign_To_Address; 135 136 --------------------------------- 137 -- Operations on Unsigned_Byte -- 138 --------------------------------- 139 140 -- It would be nice to replace these with intrinsics, but that does 141 -- not work yet (the back end would be ok, but GNAT itself objects) 142 143 type BU is mod 2 ** Unsigned_Byte'Size; 144 -- Unsigned type of same length as Unsigned_Byte 145 146 function To_B is new Ada.Unchecked_Conversion (BU, Unsigned_Byte); 147 function From_B is new Ada.Unchecked_Conversion (Unsigned_Byte, BU); 148 149 function "not" (Left : Unsigned_Byte) return Unsigned_Byte is 150 begin 151 return To_B (not From_B (Left)); 152 end "not"; 153 154 function "and" (Left, Right : Unsigned_Byte) return Unsigned_Byte is 155 begin 156 return To_B (From_B (Left) and From_B (Right)); 157 end "and"; 158 159 function "or" (Left, Right : Unsigned_Byte) return Unsigned_Byte is 160 begin 161 return To_B (From_B (Left) or From_B (Right)); 162 end "or"; 163 164 function "xor" (Left, Right : Unsigned_Byte) return Unsigned_Byte is 165 begin 166 return To_B (From_B (Left) xor From_B (Right)); 167 end "xor"; 168 169 --------------------------------- 170 -- Operations on Unsigned_Word -- 171 --------------------------------- 172 173 -- It would be nice to replace these with intrinsics, but that does 174 -- not work yet (the back end would be ok, but GNAT itself objects) 175 176 type WU is mod 2 ** Unsigned_Word'Size; 177 -- Unsigned type of same length as Unsigned_Word 178 179 function To_W is new Ada.Unchecked_Conversion (WU, Unsigned_Word); 180 function From_W is new Ada.Unchecked_Conversion (Unsigned_Word, WU); 181 182 function "not" (Left : Unsigned_Word) return Unsigned_Word is 183 begin 184 return To_W (not From_W (Left)); 185 end "not"; 186 187 function "and" (Left, Right : Unsigned_Word) return Unsigned_Word is 188 begin 189 return To_W (From_W (Left) and From_W (Right)); 190 end "and"; 191 192 function "or" (Left, Right : Unsigned_Word) return Unsigned_Word is 193 begin 194 return To_W (From_W (Left) or From_W (Right)); 195 end "or"; 196 197 function "xor" (Left, Right : Unsigned_Word) return Unsigned_Word is 198 begin 199 return To_W (From_W (Left) xor From_W (Right)); 200 end "xor"; 201 202 ------------------------------------- 203 -- Operations on Unsigned_Longword -- 204 ------------------------------------- 205 206 -- It would be nice to replace these with intrinsics, but that does 207 -- not work yet (the back end would be ok, but GNAT itself objects) 208 209 type LWU is mod 2 ** Unsigned_Longword'Size; 210 -- Unsigned type of same length as Unsigned_Longword 211 212 function To_LW is new Ada.Unchecked_Conversion (LWU, Unsigned_Longword); 213 function From_LW is new Ada.Unchecked_Conversion (Unsigned_Longword, LWU); 214 215 function "not" (Left : Unsigned_Longword) return Unsigned_Longword is 216 begin 217 return To_LW (not From_LW (Left)); 218 end "not"; 219 220 function "and" (Left, Right : Unsigned_Longword) return Unsigned_Longword is 221 begin 222 return To_LW (From_LW (Left) and From_LW (Right)); 223 end "and"; 224 225 function "or" (Left, Right : Unsigned_Longword) return Unsigned_Longword is 226 begin 227 return To_LW (From_LW (Left) or From_LW (Right)); 228 end "or"; 229 230 function "xor" (Left, Right : Unsigned_Longword) return Unsigned_Longword is 231 begin 232 return To_LW (From_LW (Left) xor From_LW (Right)); 233 end "xor"; 234 235 ------------------------------- 236 -- Operations on Unsigned_32 -- 237 ------------------------------- 238 239 -- It would be nice to replace these with intrinsics, but that does 240 -- not work yet (the back end would be ok, but GNAT itself objects) 241 242 type U32 is mod 2 ** Unsigned_32'Size; 243 -- Unsigned type of same length as Unsigned_32 244 245 function To_U32 is new Ada.Unchecked_Conversion (U32, Unsigned_32); 246 function From_U32 is new Ada.Unchecked_Conversion (Unsigned_32, U32); 247 248 function "not" (Left : Unsigned_32) return Unsigned_32 is 249 begin 250 return To_U32 (not From_U32 (Left)); 251 end "not"; 252 253 function "and" (Left, Right : Unsigned_32) return Unsigned_32 is 254 begin 255 return To_U32 (From_U32 (Left) and From_U32 (Right)); 256 end "and"; 257 258 function "or" (Left, Right : Unsigned_32) return Unsigned_32 is 259 begin 260 return To_U32 (From_U32 (Left) or From_U32 (Right)); 261 end "or"; 262 263 function "xor" (Left, Right : Unsigned_32) return Unsigned_32 is 264 begin 265 return To_U32 (From_U32 (Left) xor From_U32 (Right)); 266 end "xor"; 267 268 ------------------------------------- 269 -- Operations on Unsigned_Quadword -- 270 ------------------------------------- 271 272 -- It would be nice to replace these with intrinsics, but that does 273 -- not work yet (the back end would be ok, but GNAT itself objects) 274 275 type QWU is mod 2 ** 64; -- 64 = Unsigned_Quadword'Size 276 -- Unsigned type of same length as Unsigned_Quadword 277 278 function To_QW is new Ada.Unchecked_Conversion (QWU, Unsigned_Quadword); 279 function From_QW is new Ada.Unchecked_Conversion (Unsigned_Quadword, QWU); 280 281 function "not" (Left : Unsigned_Quadword) return Unsigned_Quadword is 282 begin 283 return To_QW (not From_QW (Left)); 284 end "not"; 285 286 function "and" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword is 287 begin 288 return To_QW (From_QW (Left) and From_QW (Right)); 289 end "and"; 290 291 function "or" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword is 292 begin 293 return To_QW (From_QW (Left) or From_QW (Right)); 294 end "or"; 295 296 function "xor" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword is 297 begin 298 return To_QW (From_QW (Left) xor From_QW (Right)); 299 end "xor"; 300 301 ----------------------- 302 -- Clear_Interlocked -- 303 ----------------------- 304 305 procedure Clear_Interlocked 306 (Bit : in out Boolean; 307 Old_Value : out Boolean) 308 is 309 begin 310 SSL.Lock_Task.all; 311 Old_Value := Bit; 312 Bit := False; 313 SSL.Unlock_Task.all; 314 end Clear_Interlocked; 315 316 procedure Clear_Interlocked 317 (Bit : in out Boolean; 318 Old_Value : out Boolean; 319 Retry_Count : Natural; 320 Success_Flag : out Boolean) 321 is 322 pragma Warnings (Off, Retry_Count); 323 324 begin 325 SSL.Lock_Task.all; 326 Old_Value := Bit; 327 Bit := False; 328 Success_Flag := True; 329 SSL.Unlock_Task.all; 330 end Clear_Interlocked; 331 332 --------------------- 333 -- Set_Interlocked -- 334 --------------------- 335 336 procedure Set_Interlocked 337 (Bit : in out Boolean; 338 Old_Value : out Boolean) 339 is 340 begin 341 SSL.Lock_Task.all; 342 Old_Value := Bit; 343 Bit := True; 344 SSL.Unlock_Task.all; 345 end Set_Interlocked; 346 347 procedure Set_Interlocked 348 (Bit : in out Boolean; 349 Old_Value : out Boolean; 350 Retry_Count : Natural; 351 Success_Flag : out Boolean) 352 is 353 pragma Warnings (Off, Retry_Count); 354 355 begin 356 SSL.Lock_Task.all; 357 Old_Value := Bit; 358 Bit := True; 359 Success_Flag := True; 360 SSL.Unlock_Task.all; 361 end Set_Interlocked; 362 363 --------------------- 364 -- Add_Interlocked -- 365 --------------------- 366 367 procedure Add_Interlocked 368 (Addend : Short_Integer; 369 Augend : in out Aligned_Word; 370 Sign : out Integer) 371 is 372 begin 373 SSL.Lock_Task.all; 374 Augend.Value := Augend.Value + Addend; 375 376 if Augend.Value < 0 then 377 Sign := -1; 378 elsif Augend.Value > 0 then 379 Sign := +1; 380 else 381 Sign := 0; 382 end if; 383 384 SSL.Unlock_Task.all; 385 end Add_Interlocked; 386 387 ---------------- 388 -- Add_Atomic -- 389 ---------------- 390 391 procedure Add_Atomic 392 (To : in out Aligned_Integer; 393 Amount : Integer) 394 is 395 begin 396 SSL.Lock_Task.all; 397 To.Value := To.Value + Amount; 398 SSL.Unlock_Task.all; 399 end Add_Atomic; 400 401 procedure Add_Atomic 402 (To : in out Aligned_Integer; 403 Amount : Integer; 404 Retry_Count : Natural; 405 Old_Value : out Integer; 406 Success_Flag : out Boolean) 407 is 408 pragma Warnings (Off, Retry_Count); 409 410 begin 411 SSL.Lock_Task.all; 412 Old_Value := To.Value; 413 To.Value := To.Value + Amount; 414 Success_Flag := True; 415 SSL.Unlock_Task.all; 416 end Add_Atomic; 417 418 procedure Add_Atomic 419 (To : in out Aligned_Long_Integer; 420 Amount : Long_Integer) 421 is 422 begin 423 SSL.Lock_Task.all; 424 To.Value := To.Value + Amount; 425 SSL.Unlock_Task.all; 426 end Add_Atomic; 427 428 procedure Add_Atomic 429 (To : in out Aligned_Long_Integer; 430 Amount : Long_Integer; 431 Retry_Count : Natural; 432 Old_Value : out Long_Integer; 433 Success_Flag : out Boolean) 434 is 435 pragma Warnings (Off, Retry_Count); 436 437 begin 438 SSL.Lock_Task.all; 439 Old_Value := To.Value; 440 To.Value := To.Value + Amount; 441 Success_Flag := True; 442 SSL.Unlock_Task.all; 443 end Add_Atomic; 444 445 ---------------- 446 -- And_Atomic -- 447 ---------------- 448 449 type IU is mod 2 ** Integer'Size; 450 type LU is mod 2 ** Long_Integer'Size; 451 452 function To_IU is new Ada.Unchecked_Conversion (Integer, IU); 453 function From_IU is new Ada.Unchecked_Conversion (IU, Integer); 454 455 function To_LU is new Ada.Unchecked_Conversion (Long_Integer, LU); 456 function From_LU is new Ada.Unchecked_Conversion (LU, Long_Integer); 457 458 procedure And_Atomic 459 (To : in out Aligned_Integer; 460 From : Integer) 461 is 462 begin 463 SSL.Lock_Task.all; 464 To.Value := From_IU (To_IU (To.Value) and To_IU (From)); 465 SSL.Unlock_Task.all; 466 end And_Atomic; 467 468 procedure And_Atomic 469 (To : in out Aligned_Integer; 470 From : Integer; 471 Retry_Count : Natural; 472 Old_Value : out Integer; 473 Success_Flag : out Boolean) 474 is 475 pragma Warnings (Off, Retry_Count); 476 477 begin 478 SSL.Lock_Task.all; 479 Old_Value := To.Value; 480 To.Value := From_IU (To_IU (To.Value) and To_IU (From)); 481 Success_Flag := True; 482 SSL.Unlock_Task.all; 483 end And_Atomic; 484 485 procedure And_Atomic 486 (To : in out Aligned_Long_Integer; 487 From : Long_Integer) 488 is 489 begin 490 SSL.Lock_Task.all; 491 To.Value := From_LU (To_LU (To.Value) and To_LU (From)); 492 SSL.Unlock_Task.all; 493 end And_Atomic; 494 495 procedure And_Atomic 496 (To : in out Aligned_Long_Integer; 497 From : Long_Integer; 498 Retry_Count : Natural; 499 Old_Value : out Long_Integer; 500 Success_Flag : out Boolean) 501 is 502 pragma Warnings (Off, Retry_Count); 503 504 begin 505 SSL.Lock_Task.all; 506 Old_Value := To.Value; 507 To.Value := From_LU (To_LU (To.Value) and To_LU (From)); 508 Success_Flag := True; 509 SSL.Unlock_Task.all; 510 end And_Atomic; 511 512 --------------- 513 -- Or_Atomic -- 514 --------------- 515 516 procedure Or_Atomic 517 (To : in out Aligned_Integer; 518 From : Integer) 519 is 520 begin 521 SSL.Lock_Task.all; 522 To.Value := From_IU (To_IU (To.Value) or To_IU (From)); 523 SSL.Unlock_Task.all; 524 end Or_Atomic; 525 526 procedure Or_Atomic 527 (To : in out Aligned_Integer; 528 From : Integer; 529 Retry_Count : Natural; 530 Old_Value : out Integer; 531 Success_Flag : out Boolean) 532 is 533 pragma Warnings (Off, Retry_Count); 534 535 begin 536 SSL.Lock_Task.all; 537 Old_Value := To.Value; 538 To.Value := From_IU (To_IU (To.Value) or To_IU (From)); 539 Success_Flag := True; 540 SSL.Unlock_Task.all; 541 end Or_Atomic; 542 543 procedure Or_Atomic 544 (To : in out Aligned_Long_Integer; 545 From : Long_Integer) 546 is 547 begin 548 SSL.Lock_Task.all; 549 To.Value := From_LU (To_LU (To.Value) or To_LU (From)); 550 SSL.Unlock_Task.all; 551 end Or_Atomic; 552 553 procedure Or_Atomic 554 (To : in out Aligned_Long_Integer; 555 From : Long_Integer; 556 Retry_Count : Natural; 557 Old_Value : out Long_Integer; 558 Success_Flag : out Boolean) 559 is 560 pragma Warnings (Off, Retry_Count); 561 562 begin 563 SSL.Lock_Task.all; 564 Old_Value := To.Value; 565 To.Value := From_LU (To_LU (To.Value) or To_LU (From)); 566 Success_Flag := True; 567 SSL.Unlock_Task.all; 568 end Or_Atomic; 569 570 ------------------------------------ 571 -- Declarations for Queue Objects -- 572 ------------------------------------ 573 574 type QR; 575 576 type QR_Ptr is access QR; 577 578 type QR is record 579 Forward : QR_Ptr; 580 Backward : QR_Ptr; 581 end record; 582 583 function To_QR_Ptr is new Ada.Unchecked_Conversion (Address, QR_Ptr); 584 function From_QR_Ptr is new Ada.Unchecked_Conversion (QR_Ptr, Address); 585 586 ------------ 587 -- Insqhi -- 588 ------------ 589 590 procedure Insqhi 591 (Item : Address; 592 Header : Address; 593 Status : out Insq_Status) 594 is 595 Hedr : constant QR_Ptr := To_QR_Ptr (Header); 596 Next : constant QR_Ptr := Hedr.Forward; 597 Itm : constant QR_Ptr := To_QR_Ptr (Item); 598 599 begin 600 SSL.Lock_Task.all; 601 602 Itm.Forward := Next; 603 Itm.Backward := Hedr; 604 Hedr.Forward := Itm; 605 606 if Next = null then 607 Status := OK_First; 608 609 else 610 Next.Backward := Itm; 611 Status := OK_Not_First; 612 end if; 613 614 SSL.Unlock_Task.all; 615 end Insqhi; 616 617 ------------ 618 -- Remqhi -- 619 ------------ 620 621 procedure Remqhi 622 (Header : Address; 623 Item : out Address; 624 Status : out Remq_Status) 625 is 626 Hedr : constant QR_Ptr := To_QR_Ptr (Header); 627 Next : constant QR_Ptr := Hedr.Forward; 628 629 begin 630 SSL.Lock_Task.all; 631 632 Item := From_QR_Ptr (Next); 633 634 if Next = null then 635 Status := Fail_Was_Empty; 636 637 else 638 Hedr.Forward := To_QR_Ptr (Item).Forward; 639 640 if Hedr.Forward = null then 641 Status := OK_Empty; 642 643 else 644 Hedr.Forward.Backward := Hedr; 645 Status := OK_Not_Empty; 646 end if; 647 end if; 648 649 SSL.Unlock_Task.all; 650 end Remqhi; 651 652 ------------ 653 -- Insqti -- 654 ------------ 655 656 procedure Insqti 657 (Item : Address; 658 Header : Address; 659 Status : out Insq_Status) 660 is 661 Hedr : constant QR_Ptr := To_QR_Ptr (Header); 662 Prev : constant QR_Ptr := Hedr.Backward; 663 Itm : constant QR_Ptr := To_QR_Ptr (Item); 664 665 begin 666 SSL.Lock_Task.all; 667 668 Itm.Backward := Prev; 669 Itm.Forward := Hedr; 670 Hedr.Backward := Itm; 671 672 if Prev = null then 673 Status := OK_First; 674 675 else 676 Prev.Forward := Itm; 677 Status := OK_Not_First; 678 end if; 679 680 SSL.Unlock_Task.all; 681 end Insqti; 682 683 ------------ 684 -- Remqti -- 685 ------------ 686 687 procedure Remqti 688 (Header : Address; 689 Item : out Address; 690 Status : out Remq_Status) 691 is 692 Hedr : constant QR_Ptr := To_QR_Ptr (Header); 693 Prev : constant QR_Ptr := Hedr.Backward; 694 695 begin 696 SSL.Lock_Task.all; 697 698 Item := From_QR_Ptr (Prev); 699 700 if Prev = null then 701 Status := Fail_Was_Empty; 702 703 else 704 Hedr.Backward := To_QR_Ptr (Item).Backward; 705 706 if Hedr.Backward = null then 707 Status := OK_Empty; 708 709 else 710 Hedr.Backward.Forward := Hedr; 711 Status := OK_Not_Empty; 712 end if; 713 end if; 714 715 SSL.Unlock_Task.all; 716 end Remqti; 717 718end System.Aux_DEC; 719