rtx pred = nvptx_get_unisimt_predicate ();
pred = gen_rtx_NE (BImode, pred, const0_rtx);
pat = gen_rtx_COND_EXEC (VOIDmode, pred, pat);
- validate_change (insn, &PATTERN (insn), pat, false);
+ bool changed_p = validate_change (insn, &PATTERN (insn), pat, false);
+ gcc_assert (changed_p);
}
}
return default_libc_has_function (fn_class, type);
}
+bool
+nvptx_mem_local_p (rtx mem)
+{
+ gcc_assert (GET_CODE (mem) == MEM);
+
+ struct address_info info;
+ decompose_mem_address (&info, mem);
+
+ if (info.base != NULL && REG_P (*info.base)
+ && REGNO_PTR_FRAME_P (REGNO (*info.base)))
+ {
+ if (TARGET_SOFT_STACK)
+ {
+ /* Frame-related doesn't mean local. */
+ }
+ else
+ return true;
+ }
+
+ return false;
+}
+
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE nvptx_option_override
(define_c_enum "unspecv" [
UNSPECV_LOCK
UNSPECV_CAS
+ UNSPECV_CAS_LOCAL
UNSPECV_XCHG
UNSPECV_BARSYNC
UNSPECV_WARPSYNC
(match_operand:SI 7 "const_int_operand")] ;; failure model
""
{
- emit_insn (gen_atomic_compare_and_swap<mode>_1
- (operands[1], operands[2], operands[3], operands[4], operands[6]));
+ if (nvptx_mem_local_p (operands[2]))
+ emit_insn (gen_atomic_compare_and_swap<mode>_1_local
+ (operands[1], operands[2], operands[3], operands[4],
+ operands[6]));
+ else
+ emit_insn (gen_atomic_compare_and_swap<mode>_1
+ (operands[1], operands[2], operands[3], operands[4],
+ operands[6]));
rtx cond = gen_reg_rtx (BImode);
emit_move_insn (cond, gen_rtx_EQ (BImode, operands[1], operands[3]));
DONE;
})
-(define_insn "atomic_compare_and_swap<mode>_1"
+(define_insn "atomic_compare_and_swap<mode>_1_local"
[(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
(unspec_volatile:SDIM
[(match_operand:SDIM 1 "memory_operand" "+m")
(match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri")
(match_operand:SDIM 3 "nvptx_nonmemory_operand" "Ri")
(match_operand:SI 4 "const_int_operand")]
- UNSPECV_CAS))
+ UNSPECV_CAS_LOCAL))
(set (match_dup 1)
- (unspec_volatile:SDIM [(const_int 0)] UNSPECV_CAS))]
+ (unspec_volatile:SDIM [(const_int 0)] UNSPECV_CAS_LOCAL))]
""
{
- struct address_info info;
- decompose_mem_address (&info, operands[1]);
- if (info.base != NULL && REG_P (*info.base)
- && REGNO_PTR_FRAME_P (REGNO (*info.base)))
- {
output_asm_insn ("{", NULL);
output_asm_insn ("\\t" ".reg.pred" "\\t" "%%eq_p;", NULL);
output_asm_insn ("\\t" ".reg%t0" "\\t" "%%val;", operands);
output_asm_insn ("\\t" "mov%t0" "\\t" "%0,%%val;", operands);
output_asm_insn ("}", NULL);
return "";
- }
+ }
+ [(set_attr "predicable" "false")])
+
+(define_insn "atomic_compare_and_swap<mode>_1"
+ [(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
+ (unspec_volatile:SDIM
+ [(match_operand:SDIM 1 "memory_operand" "+m")
+ (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri")
+ (match_operand:SDIM 3 "nvptx_nonmemory_operand" "Ri")
+ (match_operand:SI 4 "const_int_operand")]
+ UNSPECV_CAS))
+ (set (match_dup 1)
+ (unspec_volatile:SDIM [(const_int 0)] UNSPECV_CAS))]
+ ""
+ {
const char *t
- = "\\tatom%A1.cas.b%T0\\t%0, %1, %2, %3;";
+ = "%.\\tatom%A1.cas.b%T0\\t%0, %1, %2, %3;";
return nvptx_output_atomic_insn (t, operands, 1, 4);
}
- [(set_attr "atomic" "true")
- (set_attr "predicable" "false")])
+ [(set_attr "atomic" "true")])
(define_insn "atomic_exchange<mode>"
[(set (match_operand:SDIM 0 "nvptx_register_operand" "=R") ;; output
(match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))] ;; input
""
{
- struct address_info info;
- decompose_mem_address (&info, operands[1]);
- if (info.base != NULL && REG_P (*info.base)
- && REGNO_PTR_FRAME_P (REGNO (*info.base)))
+ if (nvptx_mem_local_p (operands[1]))
{
output_asm_insn ("{", NULL);
output_asm_insn ("\\t" ".reg%t0" "\\t" "%%val;", operands);
(match_dup 1))]
""
{
- struct address_info info;
- decompose_mem_address (&info, operands[1]);
- if (info.base != NULL && REG_P (*info.base)
- && REGNO_PTR_FRAME_P (REGNO (*info.base)))
+ if (nvptx_mem_local_p (operands[1]))
{
output_asm_insn ("{", NULL);
output_asm_insn ("\\t" ".reg%t0" "\\t" "%%val;", operands);
(match_dup 1))]
""
{
- struct address_info info;
- decompose_mem_address (&info, operands[1]);
- if (info.base != NULL && REG_P (*info.base)
- && REGNO_PTR_FRAME_P (REGNO (*info.base)))
+ if (nvptx_mem_local_p (operands[1]))
{
output_asm_insn ("{", NULL);
output_asm_insn ("\\t" ".reg%t0" "\\t" "%%val;", operands);
(match_dup 1))]
"<MODE>mode == SImode || TARGET_SM35"
{
- struct address_info info;
- decompose_mem_address (&info, operands[1]);
- if (info.base != NULL && REG_P (*info.base)
- && REGNO_PTR_FRAME_P (REGNO (*info.base)))
+ if (nvptx_mem_local_p (operands[1]))
{
output_asm_insn ("{", NULL);
output_asm_insn ("\\t" ".reg.b%T0" "\\t" "%%val;", operands);