")])
+
+;; Expand in-line code to clear the instruction cache between operand[0] and
+;; operand[1].
+(define_expand "clear_cache"
+ [(match_operand 0 "pmode_register_operand")
+ (match_operand 1 "pmode_register_operand")]
+ ""
+ "
+{
+ emit_insn (gen_ibar (const0_rtx));
+ DONE;
+}")
+
+(define_insn "ibar"
+ [(unspec_volatile:SI [(match_operand 0 "const_uimm15_operand")] UNSPEC_IBAR)]
+ ""
+ "ibar\t%0")
+
+(define_insn "dbar"
+ [(unspec_volatile:SI [(match_operand 0 "const_uimm15_operand")] UNSPEC_DBAR)]
+ ""
+ "dbar\t%0")
+
+
+
+;; Privileged state instruction
+
+(define_insn "cpucfg"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")]
+ UNSPEC_CPUCFG))]
+ ""
+ "cpucfg\t%0,%1"
+ [(set_attr "type" "load")
+ (set_attr "mode" "SI")])
+
+(define_insn "asrtle_d"
+ [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "d")
+ (match_operand:DI 1 "register_operand" "d")]
+ UNSPEC_ASRTLE_D)]
+ "TARGET_64BIT"
+ "asrtle.d\t%0,%1"
+ [(set_attr "type" "load")
+ (set_attr "mode" "DI")])
+
+(define_insn "asrtgt_d"
+ [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "d")
+ (match_operand:DI 1 "register_operand" "d")]
+ UNSPEC_ASRTGT_D)]
+ "TARGET_64BIT"
+ "asrtgt.d\t%0,%1"
+ [(set_attr "type" "load")
+ (set_attr "mode" "DI")])
+
+(define_insn "csrrd"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (unspec_volatile:GPR [(match_operand 1 "const_uimm14_operand")]
+ UNSPEC_CSRRD))]
+ ""
+ "csrrd\t%0,%1"
+ [(set_attr "type" "load")
+ (set_attr "mode" "")])
+
+(define_insn "csrwr"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (unspec_volatile:GPR
+ [(match_operand:GPR 1 "register_operand" "0")
+ (match_operand 2 "const_uimm14_operand")]
+ UNSPEC_CSRWR))]
+ ""
+ "csrwr\t%0,%2"
+ [(set_attr "type" "store")
+ (set_attr "mode" "")])
+
+(define_insn "csrxchg"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (unspec_volatile:GPR
+ [(match_operand:GPR 1 "register_operand" "0")
+ (match_operand:GPR 2 "register_operand" "q")
+ (match_operand 3 "const_uimm14_operand")]
+ UNSPEC_CSRXCHG))]
+ ""
+ "csrxchg\t%0,%2,%3"
+ [(set_attr "type" "load")
+ (set_attr "mode" "")])
+
+(define_insn "iocsrrd_"
+ [(set (match_operand:QHWD 0 "register_operand" "=d")
+ (unspec_volatile:QHWD [(match_operand:SI 1 "register_operand" "d")]
+ UNSPEC_IOCSRRD))]
+ ""
+ "iocsrrd.\t%0,%1"
+ [(set_attr "type" "load")
+ (set_attr "mode" "")])
+
+(define_insn "iocsrwr_"
+ [(unspec_volatile:QHWD [(match_operand:QHWD 0 "register_operand" "d")
+ (match_operand:SI 1 "register_operand" "d")]
+ UNSPEC_IOCSRWR)]
+ ""
+ "iocsrwr.\t%0,%1"
+ [(set_attr "type" "load")
+ (set_attr "mode" "")])
+
+(define_insn "cacop"
+ [(unspec_volatile:X [(match_operand 0 "const_uimm5_operand")
+ (match_operand:X 1 "register_operand" "d")
+ (match_operand 2 "const_imm12_operand")]
+ UNSPEC_CACOP)]
+ ""
+ "cacop\t%0,%1,%2"
+ [(set_attr "type" "load")
+ (set_attr "mode" "")])
+
+(define_insn "lddir"
+ [(unspec_volatile:X [(match_operand:X 0 "register_operand" "d")
+ (match_operand:X 1 "register_operand" "d")
+ (match_operand 2 "const_uimm5_operand")]
+ UNSPEC_LDDIR)]
+ ""
+ "lddir\t%0,%1,%2"
+ [(set_attr "type" "load")
+ (set_attr "mode" "")])
+
+(define_insn "ldpte"
+ [(unspec_volatile:X [(match_operand:X 0 "register_operand" "d")
+ (match_operand 1 "const_uimm5_operand")]
+ UNSPEC_LDPTE)]
+ ""
+ "ldpte\t%0,%1"
+ [(set_attr "type" "load")
+ (set_attr "mode" "")])
+
+
+;; Block moves, see loongarch.c for more details.
+;; Argument 0 is the destination
+;; Argument 1 is the source
+;; Argument 2 is the length
+;; Argument 3 is the alignment
+
+(define_expand "movmemsi"
+ [(parallel [(set (match_operand:BLK 0 "general_operand")
+ (match_operand:BLK 1 "general_operand"))
+ (use (match_operand:SI 2 ""))
+ (use (match_operand:SI 3 "const_int_operand"))])]
+ " !TARGET_MEMCPY"
+{
+ if (loongarch_expand_block_move (operands[0], operands[1], operands[2]))
+ DONE;
+ else
+ FAIL;
+})
+
+;;
+;; ....................
+;;
+;; SHIFTS
+;;
+;; ....................
+
+(define_expand "