mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-27 06:44:12 +08:00
[libatomic] Add nvptx support
Add nvptx support to libatomic. Given that atomic_test_and_set is not implemented for nvptx (PR96964), the compiler translates __atomic_test_and_set falling back onto the "Failing all else, assume a single threaded environment and simply perform the operation" case in expand_atomic_test_and_set, so it doesn't map onto an actual atomic operation. Still, that counts as supported for the configure test of libatomic, so we end up with HAVE_ATOMIC_TAS_1/2/4/8/16 == 1, and the corresponding __atomic_test_and_set_1/2/4/8/16 in libatomic all using that non-atomic implementation. Fix this by adding an atomic_test_and_set expansion for nvptx, that uses libatomics __atomic_test_and_set_1. This again makes the configure tests for HAVE_ATOMIC_TAS_1/2/4/8/16 fail, so instead we use this case in tas_n.c: ... /* If this type is smaller than word-sized, fall back to a word-sized compare-and-swap loop. */ bool SIZE(libat_test_and_set) (UTYPE *mptr, int smodel) ... which for __atomic_test_and_set_8 uses INVERT_MASK_8. Add INVERT_MASK_8 in libatomic_i.h, as well as MASK_8. Tested libatomic testsuite on nvptx. gcc/ChangeLog: PR target/96964 * config/nvptx/nvptx.md (define_expand "atomic_test_and_set"): New expansion. libatomic/ChangeLog: PR target/96898 * configure.tgt: Add nvptx. * libatomic_i.h (MASK_8, INVERT_MASK_8): New macro definition. * config/nvptx/host-config.h: New file. * config/nvptx/lock.c: New file.
This commit is contained in:
parent
8ae0de5621
commit
1554556312
@ -1667,6 +1667,22 @@
|
||||
"%.\\tatom%A1.b%T0.<logic>\\t%0, %1, %2;"
|
||||
[(set_attr "atomic" "true")])
|
||||
|
||||
(define_expand "atomic_test_and_set"
|
||||
[(match_operand:SI 0 "nvptx_register_operand") ;; bool success output
|
||||
(match_operand:QI 1 "memory_operand") ;; memory
|
||||
(match_operand:SI 2 "const_int_operand")] ;; model
|
||||
""
|
||||
{
|
||||
rtx libfunc;
|
||||
rtx addr;
|
||||
libfunc = init_one_libfunc ("__atomic_test_and_set_1");
|
||||
addr = convert_memory_address (ptr_mode, XEXP (operands[1], 0));
|
||||
emit_library_call_value (libfunc, operands[0], LCT_NORMAL, SImode,
|
||||
addr, ptr_mode,
|
||||
operands[2], SImode);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "nvptx_barsync"
|
||||
[(unspec_volatile [(match_operand:SI 0 "nvptx_nonmemory_operand" "Ri")
|
||||
(match_operand:SI 1 "const_int_operand")]
|
||||
|
56
libatomic/config/nvptx/host-config.h
Normal file
56
libatomic/config/nvptx/host-config.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Atomic Library (libatomic).
|
||||
|
||||
Libatomic 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 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Libatomic 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/>. */
|
||||
|
||||
/* Copied from libatomic/config/posix/host-config.h. */
|
||||
|
||||
/* Included after all more target-specific host-config.h. */
|
||||
|
||||
|
||||
#ifndef protect_start_end
|
||||
# ifdef HAVE_ATTRIBUTE_VISIBILITY
|
||||
# pragma GCC visibility push(hidden)
|
||||
# endif
|
||||
|
||||
void libat_lock_1 (void *ptr);
|
||||
void libat_unlock_1 (void *ptr);
|
||||
|
||||
static inline UWORD
|
||||
protect_start (void *ptr)
|
||||
{
|
||||
libat_lock_1 (ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
protect_end (void *ptr, UWORD dummy UNUSED)
|
||||
{
|
||||
libat_unlock_1 (ptr);
|
||||
}
|
||||
|
||||
# define protect_start_end 1
|
||||
# ifdef HAVE_ATTRIBUTE_VISIBILITY
|
||||
# pragma GCC visibility pop
|
||||
# endif
|
||||
#endif /* protect_start_end */
|
||||
|
||||
#include_next <host-config.h>
|
56
libatomic/config/nvptx/lock.c
Normal file
56
libatomic/config/nvptx/lock.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Atomic Library (libatomic).
|
||||
|
||||
Libatomic 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 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Libatomic 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/>. */
|
||||
|
||||
/* Functions libat_lock_n/libat_unlock_n based on GOMP_atomic_start/end in
|
||||
libgomp/atomic.c. */
|
||||
|
||||
#include "libatomic_i.h"
|
||||
|
||||
static int atomic_lock;
|
||||
|
||||
void
|
||||
libat_lock_n (void *ptr __attribute__((unused)),
|
||||
size_t n __attribute__((unused)))
|
||||
{
|
||||
while (__sync_lock_test_and_set (&atomic_lock, 1))
|
||||
; /* Spin. */
|
||||
}
|
||||
|
||||
void
|
||||
libat_unlock_n (void *ptr __attribute__((unused)),
|
||||
size_t n __attribute__((unused)))
|
||||
{
|
||||
__sync_lock_release (&atomic_lock);
|
||||
}
|
||||
|
||||
void
|
||||
libat_lock_1 (void *ptr)
|
||||
{
|
||||
libat_lock_n (ptr, 1);
|
||||
}
|
||||
|
||||
void
|
||||
libat_unlock_1 (void *ptr)
|
||||
{
|
||||
libat_unlock_n (ptr, 1);
|
||||
}
|
@ -174,6 +174,9 @@ case "${target}" in
|
||||
UNSUPPORTED=1
|
||||
;;
|
||||
|
||||
nvptx*-*-*)
|
||||
;;
|
||||
|
||||
*)
|
||||
# Who are you?
|
||||
UNSUPPORTED=1
|
||||
|
@ -109,9 +109,11 @@ typedef unsigned UWORD __attribute__((mode(word)));
|
||||
#define MASK_1 ((UWORD)0xff)
|
||||
#define MASK_2 ((UWORD)0xffff)
|
||||
#define MASK_4 ((UWORD)0xffffffff)
|
||||
#define MASK_8 ((UWORD)0xffffffffffffffff)
|
||||
#define INVERT_MASK_1 ((UWORD)WORDS_BIGENDIAN << ((WORDSIZE - 1) * CHAR_BIT))
|
||||
#define INVERT_MASK_2 ((UWORD)WORDS_BIGENDIAN << ((WORDSIZE - 2) * CHAR_BIT))
|
||||
#define INVERT_MASK_4 ((UWORD)WORDS_BIGENDIAN << ((WORDSIZE - 4) * CHAR_BIT))
|
||||
#define INVERT_MASK_8 ((UWORD)WORDS_BIGENDIAN << ((WORDSIZE - 8) * CHAR_BIT))
|
||||
|
||||
/* Most of the files in this library are compiled multiple times with
|
||||
N defined to be a power of 2 between 1 and 16. The SIZE macro is
|
||||
|
Loading…
Reference in New Issue
Block a user