gcc/ChangeLog:
* config/loongarch/sync.md (atomic_exchangeti_scq): New
define_insn.
(atomic_exchangeti): New define_expand.
---
gcc/config/loongarch/sync.md | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/gcc/config/loongarch/sync.md b/gcc/config/loongarch/sync.md
index f15f06453ee..2624bbf51cf 100644
--- a/gcc/config/loongarch/sync.md
+++ b/gcc/config/loongarch/sync.md
@@ -356,6 +356,41 @@ (define_insn "atomic_exchange<mode>"
"amswap%A3.<size>\t%0,%z2,%1"
[(set (attr "length") (const_int 4))])
+(define_insn "atomic_exchangeti_scq"
+ [(set (match_operand:TI 0 "register_operand" "=&r")
+ (unspec_volatile:TI
+ [(match_operand:TI 1 "memory_operand" "+ZB")]
+ UNSPEC_SYNC_EXCHANGE))
+ (set (match_dup 1)
+ (match_operand:TI 2 "register_operand" "rJ"))
+ (clobber (match_scratch:DI 3 "=&r"))]
+ "TARGET_64BIT && ISA_HAS_SCQ"
+{
+ output_asm_insn ("1:", operands);
+ output_asm_insn ("ll.d\t%0,%1", operands);
+ if (!ISA_HAS_LD_SEQ_SA)
+ output_asm_insn ("dbar\t0x700", operands);
+ output_asm_insn ("ld.d\t%t0,%b1,8", operands);
+ output_asm_insn ("move\t%3,%z2", operands);
+ output_asm_insn ("sc.q\t%3,%t2,%1", operands);
+ output_asm_insn ("beqz\t%3,1b", operands);
+
+ return "";
+}
+ [(set (attr "length") (const_int 24))])
+
+(define_expand "atomic_exchangeti"
+ [(match_operand:TI 0 "register_operand" "=&r")
+ (match_operand:TI 1 "memory_operand" "+ZB")
+ (match_operand:TI 2 "register_operand" "rJ")
+ (match_operand:SI 3 "const_int_operand")] ;; model
+ "TARGET_64BIT && ISA_HAS_SCQ"
+{
+ emit_insn (gen_atomic_exchangeti_scq (operands[0], operands[1],
+ operands[2]));
+ DONE;
+})
+
(define_insn "atomic_exchange<mode>_short"
[(set (match_operand:SHORT 0 "register_operand" "=&r")
(unspec_volatile:SHORT
--
2.48.1