c-family/
[official-gcc.git] / gcc / ada / s-auxdec-vms-ia64.adb
blob86bec06f2a9266603eb42a2e2d22f212c096e12d
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-2010, 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 ------------------------------------------------------------------------------
32 -- This is the Itanium/VMS version.
34 -- The Add,Clear_Interlocked subprograms are dubiously implmented due to
35 -- the lack of a single bit sync_lock_test_and_set builtin.
37 -- The "Retry" parameter is ignored due to the lack of retry builtins making
38 -- the subprograms identical to the non-retry versions.
40 pragma Style_Checks (All_Checks);
41 -- Turn off alpha ordering check on subprograms, this unit is laid
42 -- out to correspond to the declarations in the DEC 83 System unit.
44 with Interfaces;
45 package body System.Aux_DEC is
47 use type Interfaces.Unsigned_8;
49 ------------------------
50 -- Fetch_From_Address --
51 ------------------------
53 function Fetch_From_Address (A : Address) return Target is
54 type T_Ptr is access all Target;
55 function To_T_Ptr is new Ada.Unchecked_Conversion (Address, T_Ptr);
56 Ptr : constant T_Ptr := To_T_Ptr (A);
57 begin
58 return Ptr.all;
59 end Fetch_From_Address;
61 -----------------------
62 -- Assign_To_Address --
63 -----------------------
65 procedure Assign_To_Address (A : Address; T : Target) is
66 type T_Ptr is access all Target;
67 function To_T_Ptr is new Ada.Unchecked_Conversion (Address, T_Ptr);
68 Ptr : constant T_Ptr := To_T_Ptr (A);
69 begin
70 Ptr.all := T;
71 end Assign_To_Address;
73 -----------------------
74 -- Clear_Interlocked --
75 -----------------------
77 procedure Clear_Interlocked
78 (Bit : in out Boolean;
79 Old_Value : out Boolean)
81 Clr_Bit : Boolean := Bit;
82 Old_Uns : Interfaces.Unsigned_8;
84 function Sync_Lock_Test_And_Set
85 (Ptr : Address;
86 Value : Interfaces.Unsigned_8) return Interfaces.Unsigned_8;
87 pragma Import (Intrinsic, Sync_Lock_Test_And_Set,
88 "__sync_lock_test_and_set_1");
90 begin
91 Old_Uns := Sync_Lock_Test_And_Set (Clr_Bit'Address, 0);
92 Bit := Clr_Bit;
93 Old_Value := Old_Uns /= 0;
94 end Clear_Interlocked;
96 procedure Clear_Interlocked
97 (Bit : in out Boolean;
98 Old_Value : out Boolean;
99 Retry_Count : Natural;
100 Success_Flag : out Boolean)
102 pragma Unreferenced (Retry_Count);
104 Clr_Bit : Boolean := Bit;
105 Old_Uns : Interfaces.Unsigned_8;
107 function Sync_Lock_Test_And_Set
108 (Ptr : Address;
109 Value : Interfaces.Unsigned_8) return Interfaces.Unsigned_8;
110 pragma Import (Intrinsic, Sync_Lock_Test_And_Set,
111 "__sync_lock_test_and_set_1");
113 begin
114 Old_Uns := Sync_Lock_Test_And_Set (Clr_Bit'Address, 0);
115 Bit := Clr_Bit;
116 Old_Value := Old_Uns /= 0;
117 Success_Flag := True;
118 end Clear_Interlocked;
120 ---------------------
121 -- Set_Interlocked --
122 ---------------------
124 procedure Set_Interlocked
125 (Bit : in out Boolean;
126 Old_Value : out Boolean)
128 Set_Bit : Boolean := Bit;
129 Old_Uns : Interfaces.Unsigned_8;
131 function Sync_Lock_Test_And_Set
132 (Ptr : Address;
133 Value : Interfaces.Unsigned_8) return Interfaces.Unsigned_8;
134 pragma Import (Intrinsic, Sync_Lock_Test_And_Set,
135 "__sync_lock_test_and_set_1");
137 begin
138 Old_Uns := Sync_Lock_Test_And_Set (Set_Bit'Address, 1);
139 Bit := Set_Bit;
140 Old_Value := Old_Uns /= 0;
141 end Set_Interlocked;
143 procedure Set_Interlocked
144 (Bit : in out Boolean;
145 Old_Value : out Boolean;
146 Retry_Count : Natural;
147 Success_Flag : out Boolean)
149 pragma Unreferenced (Retry_Count);
151 Set_Bit : Boolean := Bit;
152 Old_Uns : Interfaces.Unsigned_8;
154 function Sync_Lock_Test_And_Set
155 (Ptr : Address;
156 Value : Interfaces.Unsigned_8) return Interfaces.Unsigned_8;
157 pragma Import (Intrinsic, Sync_Lock_Test_And_Set,
158 "__sync_lock_test_and_set_1");
159 begin
160 Old_Uns := Sync_Lock_Test_And_Set (Set_Bit'Address, 1);
161 Bit := Set_Bit;
162 Old_Value := Old_Uns /= 0;
163 Success_Flag := True;
164 end Set_Interlocked;
166 ---------------------
167 -- Add_Interlocked --
168 ---------------------
170 procedure Add_Interlocked
171 (Addend : Short_Integer;
172 Augend : in out Aligned_Word;
173 Sign : out Integer)
175 Overflowed : Boolean := False;
176 Former : Aligned_Word;
178 function Sync_Fetch_And_Add
179 (Ptr : Address;
180 Value : Short_Integer) return Short_Integer;
181 pragma Import (Intrinsic, Sync_Fetch_And_Add, "__sync_fetch_and_add_2");
183 begin
184 Former.Value := Sync_Fetch_And_Add (Augend.Value'Address, Addend);
186 if Augend.Value < 0 then
187 Sign := -1;
188 elsif Augend.Value > 0 then
189 Sign := 1;
190 else
191 Sign := 0;
192 end if;
194 if Former.Value > 0 and then Augend.Value <= 0 then
195 Overflowed := True;
196 end if;
198 if Overflowed then
199 raise Constraint_Error;
200 end if;
201 end Add_Interlocked;
203 ----------------
204 -- Add_Atomic --
205 ----------------
207 procedure Add_Atomic
208 (To : in out Aligned_Integer;
209 Amount : Integer)
211 procedure Sync_Add_And_Fetch
212 (Ptr : Address;
213 Value : Integer);
214 pragma Import (Intrinsic, Sync_Add_And_Fetch, "__sync_add_and_fetch_4");
215 begin
216 Sync_Add_And_Fetch (To.Value'Address, Amount);
217 end Add_Atomic;
219 procedure Add_Atomic
220 (To : in out Aligned_Integer;
221 Amount : Integer;
222 Retry_Count : Natural;
223 Old_Value : out Integer;
224 Success_Flag : out Boolean)
226 pragma Unreferenced (Retry_Count);
228 function Sync_Fetch_And_Add
229 (Ptr : Address;
230 Value : Integer) return Integer;
231 pragma Import (Intrinsic, Sync_Fetch_And_Add, "__sync_fetch_and_add_4");
233 begin
234 Old_Value := Sync_Fetch_And_Add (To.Value'Address, Amount);
235 Success_Flag := True;
236 end Add_Atomic;
238 procedure Add_Atomic
239 (To : in out Aligned_Long_Integer;
240 Amount : Long_Integer)
242 procedure Sync_Add_And_Fetch
243 (Ptr : Address;
244 Value : Long_Integer);
245 pragma Import (Intrinsic, Sync_Add_And_Fetch, "__sync_add_and_fetch_8");
246 begin
247 Sync_Add_And_Fetch (To.Value'Address, Amount);
248 end Add_Atomic;
250 procedure Add_Atomic
251 (To : in out Aligned_Long_Integer;
252 Amount : Long_Integer;
253 Retry_Count : Natural;
254 Old_Value : out Long_Integer;
255 Success_Flag : out Boolean)
257 pragma Unreferenced (Retry_Count);
259 function Sync_Fetch_And_Add
260 (Ptr : Address;
261 Value : Long_Integer) return Long_Integer;
262 pragma Import (Intrinsic, Sync_Fetch_And_Add, "__sync_fetch_and_add_8");
263 -- Why do we keep importing this over and over again???
265 begin
266 Old_Value := Sync_Fetch_And_Add (To.Value'Address, Amount);
267 Success_Flag := True;
268 end Add_Atomic;
270 ----------------
271 -- And_Atomic --
272 ----------------
274 procedure And_Atomic
275 (To : in out Aligned_Integer;
276 From : Integer)
278 procedure Sync_And_And_Fetch
279 (Ptr : Address;
280 Value : Integer);
281 pragma Import (Intrinsic, Sync_And_And_Fetch, "__sync_and_and_fetch_4");
282 begin
283 Sync_And_And_Fetch (To.Value'Address, From);
284 end And_Atomic;
286 procedure And_Atomic
287 (To : in out Aligned_Integer;
288 From : Integer;
289 Retry_Count : Natural;
290 Old_Value : out Integer;
291 Success_Flag : out Boolean)
293 pragma Unreferenced (Retry_Count);
295 function Sync_Fetch_And_And
296 (Ptr : Address;
297 Value : Integer) return Integer;
298 pragma Import (Intrinsic, Sync_Fetch_And_And, "__sync_fetch_and_and_4");
300 begin
301 Old_Value := Sync_Fetch_And_And (To.Value'Address, From);
302 Success_Flag := True;
303 end And_Atomic;
305 procedure And_Atomic
306 (To : in out Aligned_Long_Integer;
307 From : Long_Integer)
309 procedure Sync_And_And_Fetch
310 (Ptr : Address;
311 Value : Long_Integer);
312 pragma Import (Intrinsic, Sync_And_And_Fetch, "__sync_and_and_fetch_8");
313 begin
314 Sync_And_And_Fetch (To.Value'Address, From);
315 end And_Atomic;
317 procedure And_Atomic
318 (To : in out Aligned_Long_Integer;
319 From : Long_Integer;
320 Retry_Count : Natural;
321 Old_Value : out Long_Integer;
322 Success_Flag : out Boolean)
324 pragma Unreferenced (Retry_Count);
326 function Sync_Fetch_And_And
327 (Ptr : Address;
328 Value : Long_Integer) return Long_Integer;
329 pragma Import (Intrinsic, Sync_Fetch_And_And, "__sync_fetch_and_and_8");
331 begin
332 Old_Value := Sync_Fetch_And_And (To.Value'Address, From);
333 Success_Flag := True;
334 end And_Atomic;
336 ---------------
337 -- Or_Atomic --
338 ---------------
340 procedure Or_Atomic
341 (To : in out Aligned_Integer;
342 From : Integer)
344 procedure Sync_Or_And_Fetch
345 (Ptr : Address;
346 Value : Integer);
347 pragma Import (Intrinsic, Sync_Or_And_Fetch, "__sync_or_and_fetch_4");
349 begin
350 Sync_Or_And_Fetch (To.Value'Address, From);
351 end Or_Atomic;
353 procedure Or_Atomic
354 (To : in out Aligned_Integer;
355 From : Integer;
356 Retry_Count : Natural;
357 Old_Value : out Integer;
358 Success_Flag : out Boolean)
360 pragma Unreferenced (Retry_Count);
362 function Sync_Fetch_And_Or
363 (Ptr : Address;
364 Value : Integer) return Integer;
365 pragma Import (Intrinsic, Sync_Fetch_And_Or, "__sync_fetch_and_or_4");
367 begin
368 Old_Value := Sync_Fetch_And_Or (To.Value'Address, From);
369 Success_Flag := True;
370 end Or_Atomic;
372 procedure Or_Atomic
373 (To : in out Aligned_Long_Integer;
374 From : Long_Integer)
376 procedure Sync_Or_And_Fetch
377 (Ptr : Address;
378 Value : Long_Integer);
379 pragma Import (Intrinsic, Sync_Or_And_Fetch, "__sync_or_and_fetch_8");
380 begin
381 Sync_Or_And_Fetch (To.Value'Address, From);
382 end Or_Atomic;
384 procedure Or_Atomic
385 (To : in out Aligned_Long_Integer;
386 From : Long_Integer;
387 Retry_Count : Natural;
388 Old_Value : out Long_Integer;
389 Success_Flag : out Boolean)
391 pragma Unreferenced (Retry_Count);
393 function Sync_Fetch_And_Or
394 (Ptr : Address;
395 Value : Long_Integer) return Long_Integer;
396 pragma Import (Intrinsic, Sync_Fetch_And_Or, "__sync_fetch_and_or_8");
398 begin
399 Old_Value := Sync_Fetch_And_Or (To.Value'Address, From);
400 Success_Flag := True;
401 end Or_Atomic;
403 ------------
404 -- Insqhi --
405 ------------
407 procedure Insqhi
408 (Item : Address;
409 Header : Address;
410 Status : out Insq_Status) is
412 procedure SYS_PAL_INSQHIL
413 (STATUS : out Integer; Header : Address; ITEM : Address);
414 pragma Interface (External, SYS_PAL_INSQHIL);
415 pragma Import_Valued_Procedure (SYS_PAL_INSQHIL, "SYS$PAL_INSQHIL",
416 (Integer, Address, Address),
417 (Value, Value, Value));
419 Istat : Integer;
421 begin
422 SYS_PAL_INSQHIL (Istat, Header, Item);
424 if Istat = 0 then
425 Status := OK_Not_First;
426 elsif Istat = 1 then
427 Status := OK_First;
429 else
430 -- This status is never returned on IVMS
432 Status := Fail_No_Lock;
433 end if;
434 end Insqhi;
436 ------------
437 -- Remqhi --
438 ------------
440 procedure Remqhi
441 (Header : Address;
442 Item : out Address;
443 Status : out Remq_Status)
445 -- The removed item is returned in the second function return register,
446 -- R9 on IVMS. The VMS ABI calls for "small" records to be returned in
447 -- these registers, so inventing this odd looking record type makes that
448 -- all work.
450 type Remq is record
451 Status : Long_Integer;
452 Item : Address;
453 end record;
455 procedure SYS_PAL_REMQHIL
456 (Remret : out Remq; Header : Address);
457 pragma Interface (External, SYS_PAL_REMQHIL);
458 pragma Import_Valued_Procedure
459 (SYS_PAL_REMQHIL, "SYS$PAL_REMQHIL",
460 (Remq, Address),
461 (Value, Value));
463 -- Following variables need documentation???
465 Rstat : Long_Integer;
466 Remret : Remq;
468 begin
469 SYS_PAL_REMQHIL (Remret, Header);
471 Rstat := Remret.Status;
472 Item := Remret.Item;
474 if Rstat = 0 then
475 Status := Fail_Was_Empty;
477 elsif Rstat = 1 then
478 Status := OK_Not_Empty;
480 elsif Rstat = 2 then
481 Status := OK_Empty;
483 else
484 -- This status is never returned on IVMS
486 Status := Fail_No_Lock;
487 end if;
489 end Remqhi;
491 ------------
492 -- Insqti --
493 ------------
495 procedure Insqti
496 (Item : Address;
497 Header : Address;
498 Status : out Insq_Status) is
500 procedure SYS_PAL_INSQTIL
501 (STATUS : out Integer; Header : Address; ITEM : Address);
502 pragma Interface (External, SYS_PAL_INSQTIL);
503 pragma Import_Valued_Procedure (SYS_PAL_INSQTIL, "SYS$PAL_INSQTIL",
504 (Integer, Address, Address),
505 (Value, Value, Value));
507 Istat : Integer;
509 begin
510 SYS_PAL_INSQTIL (Istat, Header, Item);
512 if Istat = 0 then
513 Status := OK_Not_First;
515 elsif Istat = 1 then
516 Status := OK_First;
518 else
519 -- This status is never returned on IVMS
521 Status := Fail_No_Lock;
522 end if;
523 end Insqti;
525 ------------
526 -- Remqti --
527 ------------
529 procedure Remqti
530 (Header : Address;
531 Item : out Address;
532 Status : out Remq_Status)
534 -- The removed item is returned in the second function return register,
535 -- R9 on IVMS. The VMS ABI calls for "small" records to be returned in
536 -- these registers, so inventing (where is rest of this comment???)
538 type Remq is record
539 Status : Long_Integer;
540 Item : Address;
541 end record;
543 procedure SYS_PAL_REMQTIL
544 (Remret : out Remq; Header : Address);
545 pragma Interface (External, SYS_PAL_REMQTIL);
546 pragma Import_Valued_Procedure (SYS_PAL_REMQTIL, "SYS$PAL_REMQTIL",
547 (Remq, Address),
548 (Value, Value));
550 Rstat : Long_Integer;
551 Remret : Remq;
553 begin
554 SYS_PAL_REMQTIL (Remret, Header);
556 Rstat := Remret.Status;
557 Item := Remret.Item;
559 -- Wouldn't case be nicer here, and in previous similar cases ???
561 if Rstat = 0 then
562 Status := Fail_Was_Empty;
564 elsif Rstat = 1 then
565 Status := OK_Not_Empty;
567 elsif Rstat = 2 then
568 Status := OK_Empty;
569 else
570 -- This status is never returned on IVMS
572 Status := Fail_No_Lock;
573 end if;
574 end Remqti;
576 end System.Aux_DEC;