aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorXi Ruoyao <xry111@xry111.site>2025-03-01 11:46:54 +0800
committerLulu Cheng <chenglulu@loongson.cn>2025-08-18 09:09:37 +0800
commit2aca41ba9769194bc740683616b7a539019993a7 (patch)
tree89f1d486a577b5ee62fe6348473b5382b25cf624 /gcc
parent0f3c1b71daaa3f6cfc566347535a6a56662f2454 (diff)
downloadgcc-2aca41ba9769194bc740683616b7a539019993a7.zip
gcc-2aca41ba9769194bc740683616b7a539019993a7.tar.gz
gcc-2aca41ba9769194bc740683616b7a539019993a7.tar.bz2
LoongArch: Implement 16-byte atomic store with sc.q
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/loongarch/loongarch.cc11
-rw-r--r--gcc/config/loongarch/sync.md18
2 files changed, 28 insertions, 1 deletions
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index a7b6462..0935d7b 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -6223,6 +6223,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.
@@ -6493,6 +6494,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 a0129b6..b3f9efc 100644
--- a/gcc/config/loongarch/sync.md
+++ b/gcc/config/loongarch/sync.md
@@ -236,12 +236,28 @@
}
[(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);