[Bug target/96964] [nvptx] Implement __atomic_test_and_set
vries at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Sep 7 20:50:47 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96964
--- Comment #1 from Tom de Vries <vries at gcc dot gnu.org> ---
This is an attempt to implement it by using a fallback in libatomic (see also
PR96898):
...
diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md
index 4168190fa42..612240661f8 100644
--- a/gcc/config/nvptx/nvptx.md
+++ b/gcc/config/nvptx/nvptx.md
@@ -54,6 +54,7 @@
UNSPECV_LOCK
UNSPECV_CAS
UNSPECV_XCHG
+ UNSPECV_TAS
UNSPECV_BARSYNC
UNSPECV_MEMBAR
UNSPECV_MEMBAR_CTA
@@ -1667,6 +1668,35 @@
"%.\\tatom%A1.b%T0.<logic>\\t%0, %1, %2;"
[(set_attr "atomic" "true")])
+(define_insn "atomic_test_and_set"
+ [(set (match_operand:QI 0 "nvptx_register_operand" "=R")
+ (unspec_volatile:QI
+ [(match_operand:QI 1 "memory_operand" "+m")
+ (match_operand:SI 2 "const_int_operand") ;; model
+ ]
+ UNSPECV_TAS))
+ (set (match_dup 1)
+ (unspec_volatile:QI [(match_dup 1)] UNSPECV_TAS))]
+ ""
+ { operands[1] = XEXP (operands[1], 0);
+ return
+ "// BEGIN GLOBAL FUNCTION DECL: __atomic_test_and_set_1\n"
+ ".extern .func (.param .u32 %%value_out)"
+ " __atomic_test_and_set_1 (.param .u64 %%in_ar0, .param .u32
%%in_ar1);\n"
+ "{\n"
+ " .param .u32 %%value_in;\n"
+ " .param .u64 %%out_arg1;\n"
+ " .reg.u64 %%ptr;\n"
+ " cvta.global.u64 %%ptr, %1;\n"
+ " st.param.u64 [%%out_arg1],%%ptr;\n"
+ " .param .u32 %%out_arg2;\n"
+ " st.param.u32 [%%out_arg2],%2;\n"
+ " call (%%value_in),__atomic_test_and_set_1,(%%out_arg1,%%out_arg2);\n"
+ " ld.param.u32 %0,[%%value_in];\n"
+ "}";
+ }
+[(set_attr "atomic" "true")])
+
(define_insn "nvptx_barsync"
[(unspec_volatile [(match_operand:SI 0 "nvptx_nonmemory_operand" "Ri")
(match_operand:SI 1 "const_int_operand")]
...
Funnily enough, doing this has the side-effect that the fallback
__atomic_test_and_set_1 in libatomic is fixed.
More information about the Gcc-bugs
mailing list