]>
Commit | Line | Data |
---|---|---|
d6491d15 | 1 | /* AMD GCN atomic operations |
99dee823 | 2 | Copyright (C) 2020-2021 Free Software Foundation, Inc. |
d6491d15 KCY |
3 | Contributed by Mentor Graphics. |
4 | ||
5 | This file is free software; you can redistribute it and/or modify it | |
6 | under the terms of the GNU General Public License as published by the | |
7 | Free Software Foundation; either version 3, or (at your option) any | |
8 | later version. | |
9 | ||
10 | This file is distributed in the hope that it will be useful, but | |
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | General Public License for more details. | |
14 | ||
15 | Under Section 7 of GPL version 3, you are granted additional | |
16 | permissions described in the GCC Runtime Library Exception, version | |
17 | 3.1, as published by the Free Software Foundation. | |
18 | ||
19 | You should have received a copy of the GNU General Public License and | |
20 | a copy of the GCC Runtime Library Exception along with this program; | |
21 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
22 | <http://www.gnu.org/licenses/>. */ | |
23 | ||
24 | #include <stdbool.h> | |
d6491d15 KCY |
25 | |
26 | #define __SYNC_SUBWORD_COMPARE_AND_SWAP(TYPE, SIZE) \ | |
27 | \ | |
28 | TYPE \ | |
29 | __sync_val_compare_and_swap_##SIZE (TYPE *ptr, TYPE oldval, TYPE newval) \ | |
30 | { \ | |
af9bd920 KCY |
31 | unsigned int *wordptr = (unsigned int *)((__UINTPTR_TYPE__ ) ptr & ~3UL); \ |
32 | int shift = ((__UINTPTR_TYPE__ ) ptr & 3UL) * 8; \ | |
d6491d15 KCY |
33 | unsigned int valmask = (1 << (SIZE * 8)) - 1; \ |
34 | unsigned int wordmask = ~(valmask << shift); \ | |
35 | unsigned int oldword = *wordptr; \ | |
36 | for (;;) \ | |
37 | { \ | |
38 | TYPE prevval = (oldword >> shift) & valmask; \ | |
39 | if (__builtin_expect (prevval != oldval, 0)) \ | |
40 | return prevval; \ | |
41 | unsigned int newword = oldword & wordmask; \ | |
42 | newword |= ((unsigned int) newval) << shift; \ | |
43 | unsigned int prevword \ | |
44 | = __sync_val_compare_and_swap_4 (wordptr, oldword, newword); \ | |
45 | if (__builtin_expect (prevword == oldword, 1)) \ | |
46 | return oldval; \ | |
47 | oldword = prevword; \ | |
48 | } \ | |
49 | } \ | |
50 | \ | |
51 | bool \ | |
52 | __sync_bool_compare_and_swap_##SIZE (TYPE *ptr, TYPE oldval, TYPE newval) \ | |
53 | { \ | |
54 | return __sync_val_compare_and_swap_##SIZE (ptr, oldval, newval) == oldval; \ | |
55 | } | |
56 | ||
57 | __SYNC_SUBWORD_COMPARE_AND_SWAP (unsigned char, 1) | |
58 | __SYNC_SUBWORD_COMPARE_AND_SWAP (unsigned short, 2) | |
59 |