]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgomp/config/gcn/target.c
RISC-V: Cleanup debug code for SAT_* testcases [NFC]
[thirdparty/gcc.git] / libgomp / config / gcn / target.c
CommitLineData
a945c346 1/* Copyright (C) 2017-2024 Free Software Foundation, Inc.
fa499995
AS
2 Contributed by Mentor Embedded.
3
4 This file is part of the GNU Offloading and Multi Processing Library
5 (libgomp).
6
7 Libgomp is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
25
26#include "libgomp.h"
8c05d8cd 27#include "libgomp-gcn.h"
fa499995
AS
28#include <limits.h>
29
8c05d8cd
TB
30extern volatile struct gomp_offload_icvs GOMP_ADDITIONAL_ICVS;
31
a95c1911
TS
32/* Implement OpenMP 'teams' construct.
33
34 Initialize upon FIRST call. Return whether this invocation is active.
35 Depending on whether NUM_TEAMS_LOWER asks for more teams than are provided
36 in hardware, we may need to loop multiple times; in that case make sure to
37 update the team-level variable used by 'omp_get_team_num', as we then can't
38 just use '__builtin_gcn_dim_pos (0)'. */
39
7d6da11f
JJ
40bool
41GOMP_teams4 (unsigned int num_teams_lower, unsigned int num_teams_upper,
42 unsigned int thread_limit, bool first)
fa499995 43{
f9119948
TS
44 int __lds *gomp_team_num = (int __lds *) GOMP_TEAM_NUM;
45 unsigned int num_workgroups = __builtin_gcn_dim_size (0);
7d6da11f 46 if (!first)
f9119948
TS
47 {
48 unsigned int team_num;
49 if (num_workgroups > gomp_num_teams_var)
50 return false;
51 team_num = *gomp_team_num;
52 if (team_num > gomp_num_teams_var - num_workgroups)
53 return false;
54 *gomp_team_num = team_num + num_workgroups;
55 return true;
56 }
fa499995
AS
57 if (thread_limit)
58 {
59 struct gomp_task_icv *icv = gomp_icv (true);
60 icv->thread_limit_var
61 = thread_limit > INT_MAX ? UINT_MAX : thread_limit;
62 }
f9119948 63 if (!num_teams_upper)
ad0f80d9
TB
64 num_teams_upper = ((GOMP_ADDITIONAL_ICVS.nteams > 0
65 && num_workgroups > GOMP_ADDITIONAL_ICVS.nteams)
66 ? GOMP_ADDITIONAL_ICVS.nteams : num_workgroups);
f9119948
TS
67 else if (num_workgroups < num_teams_lower)
68 num_teams_upper = num_teams_lower;
69 else if (num_workgroups < num_teams_upper)
70 num_teams_upper = num_workgroups;
71 unsigned int workgroup_id = __builtin_gcn_dim_pos (0);
72 if (workgroup_id >= num_teams_upper)
7d6da11f 73 return false;
f9119948 74 *gomp_team_num = workgroup_id;
7d6da11f
JJ
75 gomp_num_teams_var = num_teams_upper - 1;
76 return true;
fa499995
AS
77}
78
79int
80omp_pause_resource (omp_pause_resource_t kind, int device_num)
81{
82 (void) kind;
83 (void) device_num;
84 return -1;
85}
86
87int
88omp_pause_resource_all (omp_pause_resource_t kind)
89{
90 (void) kind;
91 return -1;
92}
93
94ialias (omp_pause_resource)
95ialias (omp_pause_resource_all)
95d67762
JJ
96
97void
98GOMP_target_ext (int device, void (*fn) (void *), size_t mapnum,
99 void **hostaddrs, size_t *sizes, unsigned short *kinds,
100 unsigned int flags, void **depend, void **args)
101{
95d67762
JJ
102 (void) flags;
103 (void) depend;
104 (void) args;
8c05d8cd
TB
105
106 if (device != GOMP_DEVICE_HOST_FALLBACK || fn == NULL)
107 return;
108
109 /* The output data is at ((void*) kernargs)[2]. */
110 register void **kernargs = (void**) __builtin_gcn_kernarg_ptr ();
111 struct output *data = (struct output *) kernargs[2];
112 /* Reserve one slot. */
113 unsigned int index = __atomic_fetch_add (&data->next_output, 1,
114 __ATOMIC_ACQUIRE);
115
116 if ((unsigned int) (index + 1) < data->consumed)
117 abort (); /* Overflow. */
118
119 /* Spinlock while the host catches up. */
120 if (index >= 1024)
121 while (__atomic_load_n (&data->consumed, __ATOMIC_ACQUIRE)
122 <= (index - 1024))
123 asm ("s_sleep 64");
124
125 unsigned int slot = index % 1024;
6edcb5dc
TB
126 data->queue[slot].value_u64[0] = (uint64_t) fn;
127 data->queue[slot].value_u64[1] = (uint64_t) mapnum;
128 data->queue[slot].value_u64[2] = (uint64_t) hostaddrs;
129 data->queue[slot].value_u64[3] = (uint64_t) sizes;
130 data->queue[slot].value_u64[4] = (uint64_t) kinds;
131 data->queue[slot].value_u64[5] = (uint64_t) GOMP_ADDITIONAL_ICVS.device_num;
8c05d8cd
TB
132
133 data->queue[slot].type = 4; /* Reverse offload. */
134 __atomic_store_n (&data->queue[slot].written, 1, __ATOMIC_RELEASE);
135
136 /* Spinlock while the host catches up. */
137 while (__atomic_load_n (&data->queue[slot].written, __ATOMIC_ACQUIRE) != 0)
138 asm ("s_sleep 64");
95d67762
JJ
139}
140
141void
142GOMP_target_data_ext (int device, size_t mapnum, void **hostaddrs,
143 size_t *sizes, unsigned short *kinds)
144{
145 (void) device;
146 (void) mapnum;
147 (void) hostaddrs;
148 (void) sizes;
149 (void) kinds;
150 __builtin_unreachable ();
151}
152
153void
154GOMP_target_end_data (void)
155{
156 __builtin_unreachable ();
157}
158
159void
160GOMP_target_update_ext (int device, size_t mapnum, void **hostaddrs,
161 size_t *sizes, unsigned short *kinds,
162 unsigned int flags, void **depend)
163{
164 (void) device;
165 (void) mapnum;
166 (void) hostaddrs;
167 (void) sizes;
168 (void) kinds;
169 (void) flags;
170 (void) depend;
171 __builtin_unreachable ();
172}
173
174void
175GOMP_target_enter_exit_data (int device, size_t mapnum, void **hostaddrs,
176 size_t *sizes, unsigned short *kinds,
177 unsigned int flags, void **depend)
178{
179 (void) device;
180 (void) mapnum;
181 (void) hostaddrs;
182 (void) sizes;
183 (void) kinds;
184 (void) flags;
185 (void) depend;
186 __builtin_unreachable ();
187}
0beac1db
TB
188
189int
190omp_get_num_interop_properties (const omp_interop_t interop
191 __attribute__ ((unused)))
192{
193 return 0;
194}
195
196omp_intptr_t
197omp_get_interop_int (const omp_interop_t interop,
198 omp_interop_property_t property_id,
199 omp_interop_rc_t *ret_code)
200{
201 if (ret_code == NULL)
202 return 0;
203 if (property_id < omp_ipr_first || property_id >= 0)
204 *ret_code = omp_irc_out_of_range;
205 else if (interop == omp_interop_none)
206 *ret_code = omp_irc_empty;
207 else
208 *ret_code = omp_irc_other;
209 return 0;
210}
211
212void *
213omp_get_interop_ptr (const omp_interop_t interop,
214 omp_interop_property_t property_id,
215 omp_interop_rc_t *ret_code)
216{
217 if (ret_code == NULL)
218 return NULL;
219 if (property_id < omp_ipr_first || property_id >= 0)
220 *ret_code = omp_irc_out_of_range;
221 else if (interop == omp_interop_none)
222 *ret_code = omp_irc_empty;
223 else
224 *ret_code = omp_irc_other;
225 return NULL;
226}
227
228const char *
229omp_get_interop_str (const omp_interop_t interop,
230 omp_interop_property_t property_id,
231 omp_interop_rc_t *ret_code)
232{
233 if (ret_code == NULL)
234 return NULL;
235 if (property_id < omp_ipr_first || property_id >= 0)
236 *ret_code = omp_irc_out_of_range;
237 else if (interop == omp_interop_none)
238 *ret_code = omp_irc_empty;
239 else
240 *ret_code = omp_irc_other;
241 return NULL;
242}
243
244const char *
245omp_get_interop_name (const omp_interop_t interop __attribute__ ((unused)),
246 omp_interop_property_t property_id)
247{
248 static const char *prop_string[0 - omp_ipr_first]
249 = {"fr_id", "fr_name", "vendor", "vendor_name", "device_num", "platform",
250 "device", "device_context", "targetsync"};
251 if (property_id < omp_ipr_first || property_id >= 0)
252 return NULL;
253 return prop_string[omp_ipr_fr_id - property_id];
254}
255
256const char *
257omp_get_interop_type_desc (const omp_interop_t interop __attribute__ ((unused)),
258 omp_interop_property_t property_id
259 __attribute__ ((unused)))
260{
261 return NULL;
262}
263
264const char *
265omp_get_interop_rc_desc (const omp_interop_t interop __attribute__ ((unused)),
266 omp_interop_rc_t ret_code)
267{
268 static const char *rc_strings[omp_irc_no_value - omp_irc_other + 1]
269 = {"no meaningful value available",
270 "successful",
271 "provided interoperability object is equal to omp_interop_none",
272 "property ID is out of range",
273 "property type is integer; use omp_get_interop_int",
274 "property type is pointer; use omp_get_interop_ptr",
275 "property type is string; use omp_get_interop_str",
276 "obtaining properties is only supported on the initial device"};
277 /* omp_irc_other is returned by device-side omp_get_interop_{int,ptr,str};
278 the host returns for omp_irc_other NULL as it is not used. Besides the
279 three omp_interop_rc_t values used on the device side, handle host values
280 leaked to the device side. */
281 if (ret_code > omp_irc_no_value || ret_code < omp_irc_other)
282 return NULL;
283 return rc_strings[omp_irc_no_value - ret_code];
284}
285
bf4a5efa
TB
286const char *
287omp_get_uid_from_device (int device_num __attribute__ ((unused)))
288{
289 return NULL;
290}
291
292int
293omp_get_device_from_uid (const char *uid __attribute__ ((unused)))
294{
295 return omp_invalid_device;
296}
297
0beac1db
TB
298ialias (omp_get_num_interop_properties)
299ialias (omp_get_interop_int)
300ialias (omp_get_interop_ptr)
301ialias (omp_get_interop_str)
302ialias (omp_get_interop_name)
303ialias (omp_get_interop_type_desc)
304ialias (omp_get_interop_rc_desc)
bf4a5efa
TB
305ialias (omp_get_uid_from_device)
306ialias (omp_get_device_from_uid)