2 * Support file for amdgcn in newlib.
3 * Copyright (c) 2014, 2017 Mentor Graphics.
5 * The authors hereby grant permission to use, copy, modify, distribute,
6 * and license this software and its documentation for any purpose, provided
7 * that existing copyright notices are retained in all copies and that this
8 * notice is included verbatim in any distributions. No written agreement,
9 * license, or royalty fee is required for any of the authorized uses.
10 * Modifications to this software may be copyrighted by their authors
11 * and need not follow the licensing terms described here, provided that
12 * the new terms are clearly indicated on the first page of each file where
22 /* This struct must match the one used by gcn-run and libgomp.
23 It holds all the data output from a kernel (besides mapping data).
25 The base address pointer can be found at kernargs+16.
27 The next_output counter must be atomically incremented for each
28 print output. Only when the print data is fully written can the
29 "written" flag be set.
31 The buffer is circular; the host increments the consumed counter
32 and clears the written flag as it goes, opening up slots for reuse.
33 The counters always use absolute numbers. */
36 unsigned int next_output
;
47 unsigned int consumed
;
50 _READ_WRITE_RETURN_TYPE
write (int fd
, const void *buf
, size_t count
)
52 if (fd
!= 1 && fd
!= 2)
58 /* The output data is at ((void*)kernargs)[2]. */
59 #if defined(__has_builtin) && __has_builtin(__builtin_gcn_kernarg_ptr)
60 register void **kernargs
= __builtin_gcn_kernarg_ptr ();
62 register void **kernargs
asm("s8");
64 struct output
*data
= (struct output
*)kernargs
[2];
66 /* Each output slot allows 256 bytes, so reserve as many as we need. */
67 unsigned int slot_count
= ((count
+1)/256)+1;
68 unsigned int index
= __atomic_fetch_add (&data
->next_output
, slot_count
,
71 if ((unsigned int)(index
+ slot_count
) < data
->consumed
)
80 buf
+= 256, c
-= 256, index
++)
82 unsigned int slot
= index
% 1024;
84 /* Spinlock while the host catches up. */
86 while (__atomic_load_n (&data
->consumed
, __ATOMIC_ACQUIRE
)
92 memcpy (data
->queue
[slot
].msg
, buf
, c
);
93 data
->queue
[slot
].msg
[c
] = '\0';
94 data
->queue
[slot
].text
[0] = '\0';
98 memcpy (data
->queue
[slot
].msg
, buf
, 128);
99 memcpy (data
->queue
[slot
].text
, buf
+128, c
-128);
100 data
->queue
[slot
].text
[c
-128] = '\0';
104 memcpy (data
->queue
[slot
].msg
, buf
, 128);
105 memcpy (data
->queue
[slot
].text
, buf
+128, 128);
108 data
->queue
[slot
].type
= 3; /* Raw. */
109 __atomic_store_n (&data
->queue
[slot
].written
, 1, __ATOMIC_RELEASE
);