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