111
|
1 /* atomic.c -- Builtins for HSAIL atomic instructions for which
|
|
2 there is no feasible direct gcc GENERIC expression.
|
|
3
|
145
|
4 Copyright (C) 2015-2020 Free Software Foundation, Inc.
|
111
|
5 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
|
6 for General Processor Tech.
|
|
7
|
|
8 Permission is hereby granted, free of charge, to any person obtaining a
|
|
9 copy of this software and associated documentation files
|
|
10 (the "Software"), to deal in the Software without restriction, including
|
|
11 without limitation the rights to use, copy, modify, merge, publish,
|
|
12 distribute, sublicense, and/or sell copies of the Software, and to
|
|
13 permit persons to whom the Software is furnished to do so, subject to
|
|
14 the following conditions:
|
|
15
|
|
16 The above copyright notice and this permission notice shall be included
|
|
17 in all copies or substantial portions of the Software.
|
|
18
|
|
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
20 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
22 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
26 */
|
|
27
|
|
28 #include <stdint.h>
|
|
29 #include <stdio.h>
|
|
30
|
|
31 #define DO_ATOMICALLY(T, OPERATION) \
|
|
32 int done = 0; \
|
|
33 T old_value; \
|
|
34 T new_value; \
|
|
35 while (!done) \
|
|
36 { \
|
|
37 old_value = *ptr; \
|
|
38 new_value = OPERATION; \
|
|
39 done = __sync_bool_compare_and_swap (ptr, old_value, new_value); \
|
|
40 } \
|
|
41 return old_value
|
|
42
|
|
43 int32_t
|
|
44 __hsail_atomic_min_s32 (int32_t *ptr, int32_t a)
|
|
45 {
|
|
46 DO_ATOMICALLY (int32_t, (old_value < a) ? old_value : a);
|
|
47 }
|
|
48
|
|
49 int64_t
|
|
50 __hsail_atomic_min_s64 (int64_t *ptr, int64_t a)
|
|
51 {
|
|
52 DO_ATOMICALLY (int64_t, (old_value < a) ? old_value : a);
|
|
53 }
|
|
54
|
|
55 uint32_t
|
|
56 __hsail_atomic_min_u32 (uint32_t *ptr, uint32_t a)
|
|
57 {
|
|
58 DO_ATOMICALLY (uint32_t, (old_value < a) ? old_value : a);
|
|
59 }
|
|
60
|
|
61 uint64_t
|
|
62 __hsail_atomic_min_u64 (uint64_t *ptr, uint64_t a)
|
|
63 {
|
|
64 DO_ATOMICALLY (uint64_t, (old_value < a) ? old_value : a);
|
|
65 }
|
|
66
|
|
67 uint32_t
|
|
68 __hsail_atomic_max_u32 (uint32_t *ptr, uint32_t a)
|
|
69 {
|
|
70 DO_ATOMICALLY (uint32_t, (old_value > a) ? old_value : a);
|
|
71 }
|
|
72
|
|
73 int32_t
|
|
74 __hsail_atomic_max_s32 (int32_t *ptr, int32_t a)
|
|
75 {
|
|
76 DO_ATOMICALLY (int32_t, (old_value > a) ? old_value : a);
|
|
77 }
|
|
78
|
|
79 uint64_t
|
|
80 __hsail_atomic_max_u64 (uint64_t *ptr, uint64_t a)
|
|
81 {
|
|
82 DO_ATOMICALLY (uint64_t, (old_value > a) ? old_value : a);
|
|
83 }
|
|
84
|
|
85 int64_t
|
|
86 __hsail_atomic_max_s64 (int64_t *ptr, int64_t a)
|
|
87 {
|
|
88 DO_ATOMICALLY (int64_t, (old_value > a) ? old_value : a);
|
|
89 }
|
|
90
|
|
91 uint32_t
|
|
92 __hsail_atomic_wrapinc_u32 (uint32_t *ptr, uint32_t a)
|
|
93 {
|
|
94 DO_ATOMICALLY (uint32_t, (old_value >= a) ? 0 : (old_value + 1));
|
|
95 }
|
|
96
|
|
97 uint64_t
|
|
98 __hsail_atomic_wrapinc_u64 (uint64_t *ptr, uint64_t a)
|
|
99 {
|
|
100 DO_ATOMICALLY (uint64_t, (old_value >= a) ? 0 : (old_value + 1));
|
|
101 }
|
|
102
|
|
103 uint32_t
|
|
104 __hsail_atomic_wrapdec_u32 (uint32_t *ptr, uint32_t a)
|
|
105 {
|
|
106 DO_ATOMICALLY (uint32_t,
|
|
107 ((old_value == 0) || (old_value > a)) ? a : (old_value - 1));
|
|
108 }
|
|
109
|
|
110 uint64_t
|
|
111 __hsail_atomic_wrapdec_u64 (uint64_t *ptr, uint64_t a)
|
|
112 {
|
|
113 DO_ATOMICALLY (uint64_t,
|
|
114 ((old_value == 0) || (old_value > a)) ? a : (old_value - 1));
|
|
115 }
|