Message ID | 08f0684c-0a25-547b-827c-54e9266532d9@codesourcery.com |
---|---|
State | New |
Headers | show |
Series | [amdgcn] Add support for sub-word sync_compare_and_swap operations | expand |
On 08/01/2020 11:07, Kwok Cheung Yeung wrote: > +#define __sync_subword_compare_and_swap(type, size) \ Macro parameters are conventionally upper case. > + \ > +type \ > +__sync_val_compare_and_swap_##size (type *ptr, type oldval, type > newval) \ > +{ \ > + unsigned int *wordptr \ > + = (unsigned int *)((unsigned long long) ptr & ~3ULL); \ Please use "intptr_t" rather than "unsigned long long" (which should probably have been "unsigned long" anyway). > + int shift = ((unsigned long long) ptr & 3ULL) * 8; \ > + unsigned int valmask = (1 << (size * 8)) - 1; \ > + unsigned int wordmask = ~(valmask << shift); \ > + unsigned int oldword = *wordptr; \ > + for (;;) \ > + { \ > + type prevval = (oldword >> shift) & valmask; \ > + if (__builtin_expect (prevval != oldval, 0)) \ > + return prevval; \ > + unsigned int newword = oldword & wordmask; \ > + newword |= ((unsigned int) newval) << shift; \ > + unsigned int prevword \ > + = __sync_val_compare_and_swap_4 (wordptr, oldword, > newword); \ > + if (__builtin_expect (prevword == oldword, 1)) \ > + return oldval; \ > + oldword = prevword; \ > + } \ > +} \ > + \ > +bool \ > +__sync_bool_compare_and_swap_##size (type *ptr, type oldval, type > newval) \ > +{ \ > + return __sync_val_compare_and_swap_##size(ptr, oldval, newval) == > oldval; \ Space before '('. I presume all the '\' are lined up, but the patch has got mangled in the email. Please use an inline attachment. > +} > + > +__sync_subword_compare_and_swap (unsigned char, 1) > +__sync_subword_compare_and_swap (unsigned short, 2) > + > diff --git a/libgcc/config/gcn/t-amdgcn b/libgcc/config/gcn/t-amdgcn > index adbd866..fe7b5fa 100644 > --- a/libgcc/config/gcn/t-amdgcn > +++ b/libgcc/config/gcn/t-amdgcn > @@ -1,4 +1,5 @@ > -LIB2ADD += $(srcdir)/config/gcn/lib2-divmod.c \ > +LIB2ADD += $(srcdir)/config/gcn/atomic.c \ > + $(srcdir)/config/gcn/lib2-divmod.c \ > $(srcdir)/config/gcn/lib2-divmod-hi.c \ > $(srcdir)/config/gcn/unwind-gcn.c > Andrew
On 08/01/2020 11:42 am, Andrew Stubbs wrote: > On 08/01/2020 11:07, Kwok Cheung Yeung wrote: >> +#define __sync_subword_compare_and_swap(type, size) \ > > Macro parameters are conventionally upper case. > Fixed. I upper-cased the macro name as well. >> + \ >> +type \ >> +__sync_val_compare_and_swap_##size (type *ptr, type oldval, type >> newval) \ >> +{ \ >> + unsigned int *wordptr \ >> + = (unsigned int *)((unsigned long long) ptr & ~3ULL); \ > > Please use "intptr_t" rather than "unsigned long long" (which should > probably have been "unsigned long" anyway). > I used uintptr_t instead as we are doing unsigned operations (but it probably doesn't matter anyway). >> +__sync_bool_compare_and_swap_##size (type *ptr, type oldval, type >> newval) \ >> +{ \ >> + return __sync_val_compare_and_swap_##size(ptr, oldval, newval) == >> oldval; \ > > Space before '('. > Fixed. Is this version okay for trunk? Thanks Kwok From a163377f719e950b0d3820b703029d133ba83637 Mon Sep 17 00:00:00 2001 From: Kwok Cheung Yeung <kcy@codesourcery.com> Date: Thu, 21 Nov 2019 03:54:46 -0800 Subject: [PATCH] [amdgcn] Add support for sub-word sync_compare_and_swap operations 2020-01-08 Kwok Cheung Yeung <kcy@codesourcery.com> libgcc/ * config/gcn/atomic.c: New. * config/gcn/t-amdgcn (LIB2ADD): Add atomic.c. --- libgcc/config/gcn/atomic.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++ libgcc/config/gcn/t-amdgcn | 3 ++- 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 libgcc/config/gcn/atomic.c diff --git a/libgcc/config/gcn/atomic.c b/libgcc/config/gcn/atomic.c new file mode 100644 index 0000000..214c9a5 --- /dev/null +++ b/libgcc/config/gcn/atomic.c @@ -0,0 +1,60 @@ +/* AMD GCN atomic operations + Copyright (C) 2020 Free Software Foundation, Inc. + Contributed by Mentor Graphics. + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdbool.h> +#include <stdint.h> + +#define __SYNC_SUBWORD_COMPARE_AND_SWAP(TYPE, SIZE) \ + \ +TYPE \ +__sync_val_compare_and_swap_##SIZE (TYPE *ptr, TYPE oldval, TYPE newval) \ +{ \ + unsigned int *wordptr = (unsigned int *)((uintptr_t) ptr & ~3UL); \ + int shift = ((uintptr_t) ptr & 3UL) * 8; \ + unsigned int valmask = (1 << (SIZE * 8)) - 1; \ + unsigned int wordmask = ~(valmask << shift); \ + unsigned int oldword = *wordptr; \ + for (;;) \ + { \ + TYPE prevval = (oldword >> shift) & valmask; \ + if (__builtin_expect (prevval != oldval, 0)) \ + return prevval; \ + unsigned int newword = oldword & wordmask; \ + newword |= ((unsigned int) newval) << shift; \ + unsigned int prevword \ + = __sync_val_compare_and_swap_4 (wordptr, oldword, newword); \ + if (__builtin_expect (prevword == oldword, 1)) \ + return oldval; \ + oldword = prevword; \ + } \ +} \ + \ +bool \ +__sync_bool_compare_and_swap_##SIZE (TYPE *ptr, TYPE oldval, TYPE newval) \ +{ \ + return __sync_val_compare_and_swap_##SIZE (ptr, oldval, newval) == oldval; \ +} + +__SYNC_SUBWORD_COMPARE_AND_SWAP (unsigned char, 1) +__SYNC_SUBWORD_COMPARE_AND_SWAP (unsigned short, 2) + diff --git a/libgcc/config/gcn/t-amdgcn b/libgcc/config/gcn/t-amdgcn index adbd866..fe7b5fa 100644 --- a/libgcc/config/gcn/t-amdgcn +++ b/libgcc/config/gcn/t-amdgcn @@ -1,4 +1,5 @@ -LIB2ADD += $(srcdir)/config/gcn/lib2-divmod.c \ +LIB2ADD += $(srcdir)/config/gcn/atomic.c \ + $(srcdir)/config/gcn/lib2-divmod.c \ $(srcdir)/config/gcn/lib2-divmod-hi.c \ $(srcdir)/config/gcn/unwind-gcn.c
On 08/01/2020 18:18, Kwok Cheung Yeung wrote:
> Is this version okay for trunk?
OK, thanks.
Andrew
diff --git a/libgcc/config/gcn/atomic.c b/libgcc/config/gcn/atomic.c new file mode 100644 index 0000000..6514dfc --- /dev/null +++ b/libgcc/config/gcn/atomic.c @@ -0,0 +1,60 @@ +/* AMD GCN atomic operations + Copyright (C) 2020 Free Software Foundation, Inc. + Contributed by Mentor Graphics. + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdbool.h> + +#define __sync_subword_compare_and_swap(type, size) \ + \ +type \ +__sync_val_compare_and_swap_##size (type *ptr, type oldval, type newval) \ +{ \ + unsigned int *wordptr \ + = (unsigned int *)((unsigned long long) ptr & ~3ULL); \ + int shift = ((unsigned long long) ptr & 3ULL) * 8; \ + unsigned int valmask = (1 << (size * 8)) - 1; \ + unsigned int wordmask = ~(valmask << shift); \ + unsigned int oldword = *wordptr; \ + for (;;) \ + { \ + type prevval = (oldword >> shift) & valmask; \ + if (__builtin_expect (prevval != oldval, 0)) \ + return prevval; \ + unsigned int newword = oldword & wordmask; \ + newword |= ((unsigned int) newval) << shift; \ + unsigned int prevword \ + = __sync_val_compare_and_swap_4 (wordptr, oldword, newword); \ + if (__builtin_expect (prevword == oldword, 1)) \ + return oldval; \ + oldword = prevword; \ + } \ +} \ + \ +bool \ +__sync_bool_compare_and_swap_##size (type *ptr, type oldval, type newval) \ +{ \ + return __sync_val_compare_and_swap_##size(ptr, oldval, newval) == oldval; \ +} + +__sync_subword_compare_and_swap (unsigned char, 1) +__sync_subword_compare_and_swap (unsigned short, 2) + diff --git a/libgcc/config/gcn/t-amdgcn b/libgcc/config/gcn/t-amdgcn index adbd866..fe7b5fa 100644 --- a/libgcc/config/gcn/t-amdgcn +++ b/libgcc/config/gcn/t-amdgcn @@ -1,4 +1,5 @@ -LIB2ADD += $(srcdir)/config/gcn/lib2-divmod.c \ +LIB2ADD += $(srcdir)/config/gcn/atomic.c \ + $(srcdir)/config/gcn/lib2-divmod.c \ $(srcdir)/config/gcn/lib2-divmod-hi.c \ $(srcdir)/config/gcn/unwind-gcn.c