From d6491d15676b0255eaaa4f5394fbb8ec7e3c6a5f Mon Sep 17 00:00:00 2001 From: Kwok Cheung Yeung Date: Thu, 9 Jan 2020 15:35:14 +0000 Subject: [PATCH] [amdgcn] Add support for sub-word sync_compare_and_swap operations 2020-01-09 Kwok Cheung Yeung libgcc/ * config/gcn/atomic.c: New. * config/gcn/t-amdgcn (LIB2ADD): Add atomic.c. From-SVN: r280055 --- libgcc/ChangeLog | 5 ++++ libgcc/config/gcn/atomic.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++ libgcc/config/gcn/t-amdgcn | 3 ++- 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 libgcc/config/gcn/atomic.c diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 08e96e5..d72249d 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,8 @@ +2020-01-09 Kwok Cheung Yeung + + * config/gcn/atomic.c: New. + * config/gcn/t-amdgcn (LIB2ADD): Add atomic.c. + 2020-01-08 Georg-Johann Lay Implement 64-bit double functions. 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 + . */ + +#include +#include + +#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 -- 2.7.4