1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- S Y S T E M . A U X _ D E C --
9 -- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
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. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, Or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
34 pragma Style_Checks (All_Checks);
35 -- Turn off alpha ordering check on subprograms, this unit is laid
36 -- out to correspond to the declarations in the DEC 83 System unit.
38 with System.Soft_Links;
40 package body System.Aux_DEC is
42 package SSL renames System.Soft_Links;
44 -----------------------------------
45 -- Operations on Largest_Integer --
46 -----------------------------------
48 -- It would be nice to replace these with intrinsics, but that does
49 -- not work yet (the back end would be ok, but GNAT itself objects)
51 type LIU is mod 2 ** Largest_Integer'Size;
52 -- Unsigned type of same length as Largest_Integer
54 function To_LI is new Unchecked_Conversion (LIU, Largest_Integer);
55 function From_LI is new Unchecked_Conversion (Largest_Integer, LIU);
57 function "not" (Left : Largest_Integer) return Largest_Integer is
59 return To_LI (not From_LI (Left));
62 function "and" (Left, Right : Largest_Integer) return Largest_Integer is
64 return To_LI (From_LI (Left) and From_LI (Right));
67 function "or" (Left, Right : Largest_Integer) return Largest_Integer is
69 return To_LI (From_LI (Left) or From_LI (Right));
72 function "xor" (Left, Right : Largest_Integer) return Largest_Integer is
74 return To_LI (From_LI (Left) xor From_LI (Right));
77 --------------------------------------
78 -- Arithmetic Operations on Address --
79 --------------------------------------
81 -- It would be nice to replace these with intrinsics, but that does
82 -- not work yet (the back end would be ok, but GNAT itself objects)
84 Asiz : constant Integer := Integer (Address'Size) - 1;
86 type SA is range -(2 ** Asiz) .. 2 ** Asiz - 1;
87 -- Signed type of same size as Address
89 function To_A is new Unchecked_Conversion (SA, Address);
90 function From_A is new Unchecked_Conversion (Address, SA);
92 function "+" (Left : Address; Right : Integer) return Address is
94 return To_A (From_A (Left) + SA (Right));
97 function "+" (Left : Integer; Right : Address) return Address is
99 return To_A (SA (Left) + From_A (Right));
102 function "-" (Left : Address; Right : Address) return Integer is
103 pragma Unsuppress (All_Checks);
104 -- Because this can raise Constraint_Error for 64-bit addresses
107 return Integer (From_A (Left - Right));
110 function "-" (Left : Address; Right : Integer) return Address is
112 return To_A (From_A (Left) - SA (Right));
115 ------------------------
116 -- Fetch_From_Address --
117 ------------------------
119 function Fetch_From_Address (A : Address) return Target is
120 type T_Ptr is access all Target;
121 function To_T_Ptr is new Unchecked_Conversion (Address, T_Ptr);
122 Ptr : constant T_Ptr := To_T_Ptr (A);
126 end Fetch_From_Address;
128 -----------------------
129 -- Assign_To_Address --
130 -----------------------
132 procedure Assign_To_Address (A : Address; T : Target) is
133 type T_Ptr is access all Target;
134 function To_T_Ptr is new Unchecked_Conversion (Address, T_Ptr);
135 Ptr : constant T_Ptr := To_T_Ptr (A);
139 end Assign_To_Address;
141 ---------------------------------
142 -- Operations on Unsigned_Byte --
143 ---------------------------------
145 -- It would be nice to replace these with intrinsics, but that does
146 -- not work yet (the back end would be ok, but GNAT itself objects)
148 type BU is mod 2 ** Unsigned_Byte'Size;
149 -- Unsigned type of same length as Unsigned_Byte
151 function To_B is new Unchecked_Conversion (BU, Unsigned_Byte);
152 function From_B is new Unchecked_Conversion (Unsigned_Byte, BU);
154 function "not" (Left : Unsigned_Byte) return Unsigned_Byte is
156 return To_B (not From_B (Left));
159 function "and" (Left, Right : Unsigned_Byte) return Unsigned_Byte is
161 return To_B (From_B (Left) and From_B (Right));
164 function "or" (Left, Right : Unsigned_Byte) return Unsigned_Byte is
166 return To_B (From_B (Left) or From_B (Right));
169 function "xor" (Left, Right : Unsigned_Byte) return Unsigned_Byte is
171 return To_B (From_B (Left) xor From_B (Right));
174 ---------------------------------
175 -- Operations on Unsigned_Word --
176 ---------------------------------
178 -- It would be nice to replace these with intrinsics, but that does
179 -- not work yet (the back end would be ok, but GNAT itself objects)
181 type WU is mod 2 ** Unsigned_Word'Size;
182 -- Unsigned type of same length as Unsigned_Word
184 function To_W is new Unchecked_Conversion (WU, Unsigned_Word);
185 function From_W is new Unchecked_Conversion (Unsigned_Word, WU);
187 function "not" (Left : Unsigned_Word) return Unsigned_Word is
189 return To_W (not From_W (Left));
192 function "and" (Left, Right : Unsigned_Word) return Unsigned_Word is
194 return To_W (From_W (Left) and From_W (Right));
197 function "or" (Left, Right : Unsigned_Word) return Unsigned_Word is
199 return To_W (From_W (Left) or From_W (Right));
202 function "xor" (Left, Right : Unsigned_Word) return Unsigned_Word is
204 return To_W (From_W (Left) xor From_W (Right));
207 -------------------------------------
208 -- Operations on Unsigned_Longword --
209 -------------------------------------
211 -- It would be nice to replace these with intrinsics, but that does
212 -- not work yet (the back end would be ok, but GNAT itself objects)
214 type LWU is mod 2 ** Unsigned_Longword'Size;
215 -- Unsigned type of same length as Unsigned_Longword
217 function To_LW is new Unchecked_Conversion (LWU, Unsigned_Longword);
218 function From_LW is new Unchecked_Conversion (Unsigned_Longword, LWU);
220 function "not" (Left : Unsigned_Longword) return Unsigned_Longword is
222 return To_LW (not From_LW (Left));
225 function "and" (Left, Right : Unsigned_Longword) return Unsigned_Longword is
227 return To_LW (From_LW (Left) and From_LW (Right));
230 function "or" (Left, Right : Unsigned_Longword) return Unsigned_Longword is
232 return To_LW (From_LW (Left) or From_LW (Right));
235 function "xor" (Left, Right : Unsigned_Longword) return Unsigned_Longword is
237 return To_LW (From_LW (Left) xor From_LW (Right));
240 -------------------------------
241 -- Operations on Unsigned_32 --
242 -------------------------------
244 -- It would be nice to replace these with intrinsics, but that does
245 -- not work yet (the back end would be ok, but GNAT itself objects)
247 type U32 is mod 2 ** Unsigned_32'Size;
248 -- Unsigned type of same length as Unsigned_32
250 function To_U32 is new Unchecked_Conversion (U32, Unsigned_32);
251 function From_U32 is new Unchecked_Conversion (Unsigned_32, U32);
253 function "not" (Left : Unsigned_32) return Unsigned_32 is
255 return To_U32 (not From_U32 (Left));
258 function "and" (Left, Right : Unsigned_32) return Unsigned_32 is
260 return To_U32 (From_U32 (Left) and From_U32 (Right));
263 function "or" (Left, Right : Unsigned_32) return Unsigned_32 is
265 return To_U32 (From_U32 (Left) or From_U32 (Right));
268 function "xor" (Left, Right : Unsigned_32) return Unsigned_32 is
270 return To_U32 (From_U32 (Left) xor From_U32 (Right));
273 -------------------------------------
274 -- Operations on Unsigned_Quadword --
275 -------------------------------------
277 -- It would be nice to replace these with intrinsics, but that does
278 -- not work yet (the back end would be ok, but GNAT itself objects)
280 type QWU is mod 2 ** 64; -- 64 = Unsigned_Quadword'Size
281 -- Unsigned type of same length as Unsigned_Quadword
283 function To_QW is new Unchecked_Conversion (QWU, Unsigned_Quadword);
284 function From_QW is new Unchecked_Conversion (Unsigned_Quadword, QWU);
286 function "not" (Left : Unsigned_Quadword) return Unsigned_Quadword is
288 return To_QW (not From_QW (Left));
291 function "and" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword is
293 return To_QW (From_QW (Left) and From_QW (Right));
296 function "or" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword is
298 return To_QW (From_QW (Left) or From_QW (Right));
301 function "xor" (Left, Right : Unsigned_Quadword) return Unsigned_Quadword is
303 return To_QW (From_QW (Left) xor From_QW (Right));
306 -----------------------
307 -- Clear_Interlocked --
308 -----------------------
310 procedure Clear_Interlocked
311 (Bit : in out Boolean;
312 Old_Value : out Boolean)
319 end Clear_Interlocked;
321 procedure Clear_Interlocked
322 (Bit : in out Boolean;
323 Old_Value : out Boolean;
324 Retry_Count : in Natural;
325 Success_Flag : out Boolean)
327 pragma Warnings (Off, Retry_Count);
333 Success_Flag := True;
335 end Clear_Interlocked;
337 ---------------------
338 -- Set_Interlocked --
339 ---------------------
341 procedure Set_Interlocked
342 (Bit : in out Boolean;
343 Old_Value : out Boolean)
352 procedure Set_Interlocked
353 (Bit : in out Boolean;
354 Old_Value : out Boolean;
355 Retry_Count : in Natural;
356 Success_Flag : out Boolean)
358 pragma Warnings (Off, Retry_Count);
364 Success_Flag := True;
368 ---------------------
369 -- Add_Interlocked --
370 ---------------------
372 procedure Add_Interlocked
373 (Addend : in Short_Integer;
374 Augend : in out Aligned_Word;
379 Augend.Value := Augend.Value + Addend;
381 if Augend.Value < 0 then
383 elsif Augend.Value > 0 then
397 (To : in out Aligned_Integer;
402 To.Value := To.Value + Amount;
407 (To : in out Aligned_Integer;
409 Retry_Count : in Natural;
410 Old_Value : out Integer;
411 Success_Flag : out Boolean)
413 pragma Warnings (Off, Retry_Count);
417 Old_Value := To.Value;
418 To.Value := To.Value + Amount;
419 Success_Flag := True;
424 (To : in out Aligned_Long_Integer;
425 Amount : in Long_Integer)
429 To.Value := To.Value + Amount;
434 (To : in out Aligned_Long_Integer;
435 Amount : in Long_Integer;
436 Retry_Count : in Natural;
437 Old_Value : out Long_Integer;
438 Success_Flag : out Boolean)
440 pragma Warnings (Off, Retry_Count);
444 Old_Value := To.Value;
445 To.Value := To.Value + Amount;
446 Success_Flag := True;
454 type IU is mod 2 ** Integer'Size;
455 type LU is mod 2 ** Long_Integer'Size;
457 function To_IU is new Unchecked_Conversion (Integer, IU);
458 function From_IU is new Unchecked_Conversion (IU, Integer);
460 function To_LU is new Unchecked_Conversion (Long_Integer, LU);
461 function From_LU is new Unchecked_Conversion (LU, Long_Integer);
464 (To : in out Aligned_Integer;
469 To.Value := From_IU (To_IU (To.Value) and To_IU (From));
474 (To : in out Aligned_Integer;
476 Retry_Count : in Natural;
477 Old_Value : out Integer;
478 Success_Flag : out Boolean)
480 pragma Warnings (Off, Retry_Count);
484 Old_Value := To.Value;
485 To.Value := From_IU (To_IU (To.Value) and To_IU (From));
486 Success_Flag := True;
491 (To : in out Aligned_Long_Integer;
492 From : in Long_Integer)
496 To.Value := From_LU (To_LU (To.Value) and To_LU (From));
501 (To : in out Aligned_Long_Integer;
502 From : in Long_Integer;
503 Retry_Count : in Natural;
504 Old_Value : out Long_Integer;
505 Success_Flag : out Boolean)
507 pragma Warnings (Off, Retry_Count);
511 Old_Value := To.Value;
512 To.Value := From_LU (To_LU (To.Value) and To_LU (From));
513 Success_Flag := True;
522 (To : in out Aligned_Integer;
527 To.Value := From_IU (To_IU (To.Value) or To_IU (From));
532 (To : in out Aligned_Integer;
534 Retry_Count : in Natural;
535 Old_Value : out Integer;
536 Success_Flag : out Boolean)
538 pragma Warnings (Off, Retry_Count);
542 Old_Value := To.Value;
543 To.Value := From_IU (To_IU (To.Value) or To_IU (From));
544 Success_Flag := True;
549 (To : in out Aligned_Long_Integer;
550 From : in Long_Integer)
554 To.Value := From_LU (To_LU (To.Value) or To_LU (From));
559 (To : in out Aligned_Long_Integer;
560 From : in Long_Integer;
561 Retry_Count : in Natural;
562 Old_Value : out Long_Integer;
563 Success_Flag : out Boolean)
565 pragma Warnings (Off, Retry_Count);
569 Old_Value := To.Value;
570 To.Value := From_LU (To_LU (To.Value) or To_LU (From));
571 Success_Flag := True;
575 ------------------------------------
576 -- Declarations for Queue Objects --
577 ------------------------------------
581 type QR_Ptr is access QR;
588 function To_QR_Ptr is new Unchecked_Conversion (Address, QR_Ptr);
589 function From_QR_Ptr is new Unchecked_Conversion (QR_Ptr, Address);
598 Status : out Insq_Status)
600 Hedr : constant QR_Ptr := To_QR_Ptr (Header);
601 Next : constant QR_Ptr := Hedr.Forward;
602 Itm : constant QR_Ptr := To_QR_Ptr (Item);
608 Itm.Backward := Hedr;
615 Next.Backward := Itm;
616 Status := OK_Not_First;
627 (Header : in Address;
629 Status : out Remq_Status)
631 Hedr : constant QR_Ptr := To_QR_Ptr (Header);
632 Next : constant QR_Ptr := Hedr.Forward;
637 Item := From_QR_Ptr (Next);
640 Status := Fail_Was_Empty;
643 Hedr.Forward := To_QR_Ptr (Item).Forward;
645 if Hedr.Forward = null then
649 Hedr.Forward.Backward := Hedr;
650 Status := OK_Not_Empty;
664 Status : out Insq_Status)
666 Hedr : constant QR_Ptr := To_QR_Ptr (Header);
667 Prev : constant QR_Ptr := Hedr.Backward;
668 Itm : constant QR_Ptr := To_QR_Ptr (Item);
673 Itm.Backward := Prev;
675 Hedr.Backward := Itm;
682 Status := OK_Not_First;
693 (Header : in Address;
695 Status : out Remq_Status)
697 Hedr : constant QR_Ptr := To_QR_Ptr (Header);
698 Prev : constant QR_Ptr := Hedr.Backward;
703 Item := From_QR_Ptr (Prev);
706 Status := Fail_Was_Empty;
709 Hedr.Backward := To_QR_Ptr (Item).Backward;
711 if Hedr.Backward = null then
715 Hedr.Backward.Forward := Hedr;
716 Status := OK_Not_Empty;