------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S Y S T E M . A U X _ D E C -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2024, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/Or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- As a special exception under Section 7 of GPL version 3, you are granted -- -- additional permissions described in the GCC Runtime Library Exception, -- -- version 3.1, as published by the Free Software Foundation. -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ pragma Style_Checks (All_Checks); -- Turn off alpha ordering check on subprograms, this unit is laid -- out to correspond to the declarations in the DEC 83 System unit. with System.Soft_Links; package body System.Aux_DEC is package SSL renames System.Soft_Links; ----------------------------------- -- Operations on Largest_Integer -- ----------------------------------- -- It would be nice to replace these with intrinsics, but that does -- not work yet (the back end would be ok, but GNAT itself objects) type LIU is mod 2 ** Largest_Integer'Size; -- Unsigned type of same length as Largest_Integer function To_LI is new Ada.Unchecked_Conversion (LIU, Largest_Integer); function From_LI is new Ada.Unchecked_Conversion (Largest_Integer, LIU); function "not" (Left : Largest_Integer) return Largest_Integer is begin return To_LI (not From_LI (Left)); end "not"; function "and" (Left, Right : Largest_Integer) return Largest_Integer is begin return To_LI (From_LI (Left) and From_LI (Right)); end "and"; function "or" (Left, Right : Largest_Integer) return Largest_Integer is begin return To_LI (From_LI (Left) or From_LI (Right)); end "or"; function "xor" (Left, Right : Largest_Integer) return Largest_Integer is begin return To_LI (From_LI (Left) xor From_LI (Right)); end "xor"; -------------------------------------- -- Arithmetic Operations on Address -- -------------------------------------- -- It would be nice to replace these with intrinsics, but that does -- not work yet (the back end would be ok, but GNAT itself objects) Asiz : constant Integer := Integer (Address'Size) - 1; type SA is range -(2 ** Asiz) .. 2 ** Asiz - 1; -- Signed type of same size as Address function To_A is new Ada.Unchecked_Conversion (SA, Address); function From_A is new Ada.Unchecked_Conversion (Address, SA); function "+" (Left : Address; Right : Integer) return Address is begin return To_A (From_A (Left) + SA (Right)); end "+"; function "+" (Left : Integer; Right : Address) return Address is begin return To_A (SA (Left) + From_A (Right)); end "+"; function "-" (Left : Address; Right : Address) return Integer is pragma Unsuppress (All_Checks); -- Because this can raise Constraint_Error for 64-bit addresses begin return Integer (From_A (Left) - From_A (Right)); end "-"; function "-" (Left : Address; Right : Integer) return Address is begin return To_A (From_A (Left) - SA (Right)); end "-"; ------------------------ -- Fetch_From_Address -- ------------------------ function Fetch_From_Address (A : Address) return Target is type T_Ptr is access all Target; function To_T_Ptr is new Ada.Unchecked_Conversion (Address, T_Ptr); Ptr : constant T_Ptr := To_T_Ptr (A); begin return Ptr.all; end Fetch_From_Address; ----------------------- -- Assign_To_Address -- ----------------------- procedure Assign_To_Address (A : Address; T : Target) is type T_Ptr is access all Target; function To_T_Ptr is new Ada.Unchecked_Conversion (Address, T_Ptr); Ptr : constant T_Ptr := To_T_Ptr (A); begin Ptr.all := T; end Assign_To_Address; --------------------------------- -- Operations on Unsigned_Byte -- --------------------------------- -- It would be nice to replace these with intrinsics, but that does -- not work yet (the back end would be ok, but GNAT itself objects) type BU is mod 2 ** Unsigned_Byte'Size; -- Unsigned type of same length as Unsigned_Byte function To_B is new Ada.Unchecked_Conversion (BU, Unsigned_Byte); function From_B is new Ada.Unchecked_Conversion (Unsigned_Byte, BU); function "not" (Left : Unsigned_Byte) return Unsigned_Byte is begin return To_B (not From_B (Left)); end "not"; function "and" (Left, Right : Unsigned_Byte) return Unsigned_Byte is begin return To_B (From_B (Left) and From_B (Right)); end "and"; function "or" (Left, Right : Unsigned_Byte) return Unsigned_Byte is begin return To_B (From_B (Left) or From_B (Right)); end "or"; function "xor" (Left, Right : Unsigned_Byte) return Unsigned_Byte is begin return To_B (From_B (Left) xor From_B (Right)); end "xor"; --------------------------------- -- Operations on Unsigned_Word -- --------------------------------- -- It would be nice to replace these with intrinsics, but that does -- not work yet (the back end would be ok, but GNAT itself objects) type WU is mod 2 ** Unsigned_Word'Size; -- Unsigned type of same length as Unsigned_Word function To_W is new Ada.Unchecked_Conversion (WU, Unsigned_Word); function From_W is new Ada.Unchecked_Conversion (Unsigned_Word, WU); function "not" (Left : Unsigned_Word) return Unsigned_Word is begin return To_W (not From_W (Left)); end "not"; function "and" (Left, Right : Unsigned_Word) return Unsigned_Word is begin return To_W (From_W (Left) and From_W (Right)); end "and"; function "or" (Left, Right : Unsigned_Word) return Unsigned_Word is begin return To_W (From_W (Left) or From_W (Right)); end "or"; function "xor" (Left, Right : Unsigned_Word) return Unsigned_Word is begin return To_W (From_W (Left) xor From_W (Right)); end "xor"; ------------------------------------- -- Operations on Unsigned_Longword -- ------------------------------------- -- It would be nice to replace these with intrinsics, but that does -- not work yet (the back end would be ok, but GNAT itself objects) type LWU is mod 2 ** Unsigned_Longword'Size; -- Unsigned type of same length as Unsigned_Longword function To_LW is new Ada.Unchecked_Conversion (LWU, Unsigned_Longword); function From_LW is new Ada.Unchecked_Conversion (Unsigned_Longword, LWU); function "not" (Left : Unsigned_Longword) return Unsigned_Longword is begin return To_LW (not From_LW (Left)); end "not"; function "and" (Left, Right : Unsigned_Longword) return Unsigned_Longword is begin return To_LW (From_LW (Left) and From_LW (Right)); end "and"; function "or" (Left, Right : Unsigned_Longword) return Unsigned_Longword is begin return To_LW (From_LW (Left) or From_LW (Right)); end "or"; function "xor" (Left, Right : Unsigned_Longword) return Unsigned_Longword is begin return To_LW (From_LW (Left) xor From_LW (Right)); end "xor"; ------------------------------- -- Operations on Unsigned_32 -- ------------------------------- -- It would be nice to replace these with intrinsics, but that does -- not work yet (the back end would be ok, but GNAT itself objects) type U32 is mod 2 ** Unsigned_32'Size; -- Unsigned type of same length as Unsigned_32 function To_U32 is new Ada.Unchecked_Conversion (U32, Unsigned_32); function From_U32 is new Ada.Unchecked_Conversion (Unsigned_32, U32); function "not" (Left : Unsigned_32) return Unsigned_32 is begin return To_U32 (not From_U32 (Left)); end "not"; function "and" (Left, Right : Unsigned_32) return Unsigned_32 is begin return To_U32 (From_U32 (Left) and From_U32 (Right)); end "and"; function "or" (Left, Right : Unsigned_32) return Unsigned_32 is begin return To_U32 (From_U32 (Left) or From_U32 (Right)); end "or"; function "xor" (Left, Right : Unsigned_32) return Unsigned_32 is begin return To_U32 (From_U32 (Left) xor From_U32 (Right)); end "xor"; ------------------------------------- -- Operations on Unsigned_Quadword -- ------------------------------------- -- It would be nice to replace these with intrinsics, but that does -- not work yet (the back end would be ok, but GNAT itself objects) type QWU is mod 2 ** 64; -- 64 = Unsigned_Quadword'Size -- Unsigned type of same length as Unsigned_Quadword function To_QW is new Ada.Unchecked_Conversion (QWU, Unsigned_Quadword); function From_QW is new Ada.Unchecked_Conversion (Unsigned_Quadword, QWU); function "not" (Left : Unsigned_Quadword) return Unsigned_Quadword is begin return To_QW (not From_QW (Left)); end "not"; function "and" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword is begin return To_QW (From_QW (Left) and From_QW (Right)); end "and"; function "or" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword is begin return To_QW (From_QW (Left) or From_QW (Right)); end "or"; function "xor" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword is begin return To_QW (From_QW (Left) xor From_QW (Right)); end "xor"; ----------------------- -- Clear_Interlocked -- ----------------------- procedure Clear_Interlocked (Bit : in out Boolean; Old_Value : out Boolean) is begin SSL.Lock_Task.all; Old_Value := Bit; Bit := False; SSL.Unlock_Task.all; end Clear_Interlocked; procedure Clear_Interlocked (Bit : in out Boolean; Old_Value : out Boolean; Retry_Count : Natural; Success_Flag : out Boolean) is pragma Warnings (Off, Retry_Count); begin SSL.Lock_Task.all; Old_Value := Bit; Bit := False; Success_Flag := True; SSL.Unlock_Task.all; end Clear_Interlocked; --------------------- -- Set_Interlocked -- --------------------- procedure Set_Interlocked (Bit : in out Boolean; Old_Value : out Boolean) is begin SSL.Lock_Task.all; Old_Value := Bit; Bit := True; SSL.Unlock_Task.all; end Set_Interlocked; procedure Set_Interlocked (Bit : in out Boolean; Old_Value : out Boolean; Retry_Count : Natural; Success_Flag : out Boolean) is pragma Warnings (Off, Retry_Count); begin SSL.Lock_Task.all; Old_Value := Bit; Bit := True; Success_Flag := True; SSL.Unlock_Task.all; end Set_Interlocked; --------------------- -- Add_Interlocked -- --------------------- procedure Add_Interlocked (Addend : Short_Integer; Augend : in out Aligned_Word; Sign : out Integer) is begin SSL.Lock_Task.all; Augend.Value := Augend.Value + Addend; if Augend.Value < 0 then Sign := -1; elsif Augend.Value > 0 then Sign := +1; else Sign := 0; end if; SSL.Unlock_Task.all; end Add_Interlocked; ---------------- -- Add_Atomic -- ---------------- procedure Add_Atomic (To : in out Aligned_Integer; Amount : Integer) is begin SSL.Lock_Task.all; To.Value := To.Value + Amount; SSL.Unlock_Task.all; end Add_Atomic; procedure Add_Atomic (To : in out Aligned_Integer; Amount : Integer; Retry_Count : Natural; Old_Value : out Integer; Success_Flag : out Boolean) is pragma Warnings (Off, Retry_Count); begin SSL.Lock_Task.all; Old_Value := To.Value; To.Value := To.Value + Amount; Success_Flag := True; SSL.Unlock_Task.all; end Add_Atomic; procedure Add_Atomic (To : in out Aligned_Long_Integer; Amount : Long_Integer) is begin SSL.Lock_Task.all; To.Value := To.Value + Amount; SSL.Unlock_Task.all; end Add_Atomic; procedure Add_Atomic (To : in out Aligned_Long_Integer; Amount : Long_Integer; Retry_Count : Natural; Old_Value : out Long_Integer; Success_Flag : out Boolean) is pragma Warnings (Off, Retry_Count); begin SSL.Lock_Task.all; Old_Value := To.Value; To.Value := To.Value + Amount; Success_Flag := True; SSL.Unlock_Task.all; end Add_Atomic; ---------------- -- And_Atomic -- ---------------- type IU is mod 2 ** Integer'Size; type LU is mod 2 ** Long_Integer'Size; function To_IU is new Ada.Unchecked_Conversion (Integer, IU); function From_IU is new Ada.Unchecked_Conversion (IU, Integer); function To_LU is new Ada.Unchecked_Conversion (Long_Integer, LU); function From_LU is new Ada.Unchecked_Conversion (LU, Long_Integer); procedure And_Atomic (To : in out Aligned_Integer; From : Integer) is begin SSL.Lock_Task.all; To.Value := From_IU (To_IU (To.Value) and To_IU (From)); SSL.Unlock_Task.all; end And_Atomic; procedure And_Atomic (To : in out Aligned_Integer; From : Integer; Retry_Count : Natural; Old_Value : out Integer; Success_Flag : out Boolean) is pragma Warnings (Off, Retry_Count); begin SSL.Lock_Task.all; Old_Value := To.Value; To.Value := From_IU (To_IU (To.Value) and To_IU (From)); Success_Flag := True; SSL.Unlock_Task.all; end And_Atomic; procedure And_Atomic (To : in out Aligned_Long_Integer; From : Long_Integer) is begin SSL.Lock_Task.all; To.Value := From_LU (To_LU (To.Value) and To_LU (From)); SSL.Unlock_Task.all; end And_Atomic; procedure And_Atomic (To : in out Aligned_Long_Integer; From : Long_Integer; Retry_Count : Natural; Old_Value : out Long_Integer; Success_Flag : out Boolean) is pragma Warnings (Off, Retry_Count); begin SSL.Lock_Task.all; Old_Value := To.Value; To.Value := From_LU (To_LU (To.Value) and To_LU (From)); Success_Flag := True; SSL.Unlock_Task.all; end And_Atomic; --------------- -- Or_Atomic -- --------------- procedure Or_Atomic (To : in out Aligned_Integer; From : Integer) is begin SSL.Lock_Task.all; To.Value := From_IU (To_IU (To.Value) or To_IU (From)); SSL.Unlock_Task.all; end Or_Atomic; procedure Or_Atomic (To : in out Aligned_Integer; From : Integer; Retry_Count : Natural; Old_Value : out Integer; Success_Flag : out Boolean) is pragma Warnings (Off, Retry_Count); begin SSL.Lock_Task.all; Old_Value := To.Value; To.Value := From_IU (To_IU (To.Value) or To_IU (From)); Success_Flag := True; SSL.Unlock_Task.all; end Or_Atomic; procedure Or_Atomic (To : in out Aligned_Long_Integer; From : Long_Integer) is begin SSL.Lock_Task.all; To.Value := From_LU (To_LU (To.Value) or To_LU (From)); SSL.Unlock_Task.all; end Or_Atomic; procedure Or_Atomic (To : in out Aligned_Long_Integer; From : Long_Integer; Retry_Count : Natural; Old_Value : out Long_Integer; Success_Flag : out Boolean) is pragma Warnings (Off, Retry_Count); begin SSL.Lock_Task.all; Old_Value := To.Value; To.Value := From_LU (To_LU (To.Value) or To_LU (From)); Success_Flag := True; SSL.Unlock_Task.all; end Or_Atomic; ------------------------------------ -- Declarations for Queue Objects -- ------------------------------------ type QR; type QR_Ptr is access QR; type QR is record Forward : QR_Ptr; Backward : QR_Ptr; end record; function To_QR_Ptr is new Ada.Unchecked_Conversion (Address, QR_Ptr); function From_QR_Ptr is new Ada.Unchecked_Conversion (QR_Ptr, Address); ------------ -- Insqhi -- ------------ procedure Insqhi (Item : Address; Header : Address; Status : out Insq_Status) is Hedr : constant QR_Ptr := To_QR_Ptr (Header); Next : constant QR_Ptr := Hedr.Forward; Itm : constant QR_Ptr := To_QR_Ptr (Item); begin SSL.Lock_Task.all; Itm.Forward := Next; Itm.Backward := Hedr; Hedr.Forward := Itm; if Next = null then Status := OK_First; else Next.Backward := Itm; Status := OK_Not_First; end if; SSL.Unlock_Task.all; end Insqhi; ------------ -- Remqhi -- ------------ procedure Remqhi (Header : Address; Item : out Address; Status : out Remq_Status) is Hedr : constant QR_Ptr := To_QR_Ptr (Header); Next : constant QR_Ptr := Hedr.Forward; begin SSL.Lock_Task.all; Item := From_QR_Ptr (Next); if Next = null then Status := Fail_Was_Empty; else Hedr.Forward := To_QR_Ptr (Item).Forward; if Hedr.Forward = null then Status := OK_Empty; else Hedr.Forward.Backward := Hedr; Status := OK_Not_Empty; end if; end if; SSL.Unlock_Task.all; end Remqhi; ------------ -- Insqti -- ------------ procedure Insqti (Item : Address; Header : Address; Status : out Insq_Status) is Hedr : constant QR_Ptr := To_QR_Ptr (Header); Prev : constant QR_Ptr := Hedr.Backward; Itm : constant QR_Ptr := To_QR_Ptr (Item); begin SSL.Lock_Task.all; Itm.Backward := Prev; Itm.Forward := Hedr; Hedr.Backward := Itm; if Prev = null then Status := OK_First; else Prev.Forward := Itm; Status := OK_Not_First; end if; SSL.Unlock_Task.all; end Insqti; ------------ -- Remqti -- ------------ procedure Remqti (Header : Address; Item : out Address; Status : out Remq_Status) is Hedr : constant QR_Ptr := To_QR_Ptr (Header); Prev : constant QR_Ptr := Hedr.Backward; begin SSL.Lock_Task.all; Item := From_QR_Ptr (Prev); if Prev = null then Status := Fail_Was_Empty; else Hedr.Backward := To_QR_Ptr (Item).Backward; if Hedr.Backward = null then Status := OK_Empty; else Hedr.Backward.Forward := Hedr; Status := OK_Not_Empty; end if; end if; SSL.Unlock_Task.all; end Remqti; end System.Aux_DEC;