When LSX is not available but sc.q is (for example on LA664 where the SIMD unit is not enabled), we can use a LL-SC loop for 16-byte atomic store.
gcc/ChangeLog: * config/loongarch/loongarch.cc (loongarch_print_operand_reloc): Accept "%t" for printing the number of the 64-bit machine register holding the upper half of a TImode. * config/loongarch/sync.md (atomic_storeti_scq): New define_insn. (atomic_storeti): expand to atomic_storeti_scq if !ISA_HAS_LSX. --- gcc/config/loongarch/loongarch.cc | 11 +++++++++++ gcc/config/loongarch/sync.md | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 469aa3eb1b5..eb3baac7019 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -6208,6 +6208,7 @@ loongarch_print_operand_reloc (FILE *file, rtx op, bool hi64_part, 'r' Print address 12-31bit relocation associated with OP. 'R' Print address 32-51bit relocation associated with OP. 'T' Print a comment marker if %G outputs nothing. + 't' Print the register containing the higher 64 bits of a TImode. 'u' Print a LASX register. 'v' Print the insn size suffix b, h, w or d for vector modes V16QI, V8HI, V4SI, V2SI, and w, d for vector modes V4SF, V2DF respectively. @@ -6478,6 +6479,16 @@ loongarch_print_operand (FILE *file, rtx op, int letter) } break; + case 't': + if (GET_MODE (op) != TImode + || (op != CONST0_RTX (TImode) && code != REG)) + { + output_operand_lossage ("invalid use of '%%%c'", letter); + break; + } + op = loongarch_subword (op, 1); + letter = 'z'; + /* fall through */ default: switch (code) { diff --git a/gcc/config/loongarch/sync.md b/gcc/config/loongarch/sync.md index a0129b62a45..b3f9efc79f5 100644 --- a/gcc/config/loongarch/sync.md +++ b/gcc/config/loongarch/sync.md @@ -236,12 +236,28 @@ (define_insn "atomic_storeti_lsx" } [(set (attr "length") (const_int 12))]) +(define_insn "atomic_storeti_scq" + [(set (match_operand:TI 0 "memory_operand" "=m") + (unspec_volatile:TI + [(match_operand:TI 1 "register_operand" "r")] + UNSPEC_ATOMIC_STORE)) + (clobber (match_scratch:DI 2 "=&r"))] + "TARGET_64BIT && ISA_HAS_SCQ" + "1:\\n\\tll.d\t$r0,%0\n\tmove\t%2,%1\n\tsc.q\t%2,%t1,%0\n\tbeqz\t%2,1b" + [(set (attr "length") (const_int 16))]) + (define_expand "atomic_storeti" [(match_operand:TI 0 "memory_operand" "=m") (match_operand:TI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "const_int_operand")] - "ISA_HAS_LSX && TARGET_64BIT" + "TARGET_64BIT && (ISA_HAS_LSX || ISA_HAS_SCQ)" { + if (!ISA_HAS_LSX) + { + emit_insn (gen_atomic_storeti_scq (operands[0], operands[1])); + DONE; + } + rtx vr = gen_reg_rtx (V2DImode), op1 = operands[1]; rtvec v = rtvec_alloc (2); -- 2.48.1