RISCVInstrInfoA.td 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. //===-- RISCVInstrInfoA.td - RISC-V 'A' instructions -------*- tablegen -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file describes the RISC-V instructions from the standard 'A', Atomic
  10. // Instructions extension.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //===----------------------------------------------------------------------===//
  14. // Instruction class templates
  15. //===----------------------------------------------------------------------===//
  16. let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
  17. class LR_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
  18. : RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO,
  19. (outs GPR:$rd), (ins GPRMemZeroOffset:$rs1),
  20. opcodestr, "$rd, $rs1"> {
  21. let rs2 = 0;
  22. }
  23. multiclass LR_r_aq_rl<bits<3> funct3, string opcodestr> {
  24. def "" : LR_r<0, 0, funct3, opcodestr>;
  25. def _AQ : LR_r<1, 0, funct3, opcodestr # ".aq">;
  26. def _RL : LR_r<0, 1, funct3, opcodestr # ".rl">;
  27. def _AQ_RL : LR_r<1, 1, funct3, opcodestr # ".aqrl">;
  28. }
  29. let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in
  30. class AMO_rr<bits<5> funct5, bit aq, bit rl, bits<3> funct3, string opcodestr>
  31. : RVInstRAtomic<funct5, aq, rl, funct3, OPC_AMO,
  32. (outs GPR:$rd), (ins GPRMemZeroOffset:$rs1, GPR:$rs2),
  33. opcodestr, "$rd, $rs2, $rs1">;
  34. multiclass AMO_rr_aq_rl<bits<5> funct5, bits<3> funct3, string opcodestr> {
  35. def "" : AMO_rr<funct5, 0, 0, funct3, opcodestr>;
  36. def _AQ : AMO_rr<funct5, 1, 0, funct3, opcodestr # ".aq">;
  37. def _RL : AMO_rr<funct5, 0, 1, funct3, opcodestr # ".rl">;
  38. def _AQ_RL : AMO_rr<funct5, 1, 1, funct3, opcodestr # ".aqrl">;
  39. }
  40. multiclass AtomicStPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
  41. ValueType vt = XLenVT> {
  42. def : Pat<(StoreOp (AddrRegImm GPR:$rs1, simm12:$imm12), (vt StTy:$rs2)),
  43. (Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>;
  44. }
  45. //===----------------------------------------------------------------------===//
  46. // Instructions
  47. //===----------------------------------------------------------------------===//
  48. let Predicates = [HasStdExtA] in {
  49. defm LR_W : LR_r_aq_rl<0b010, "lr.w">, Sched<[WriteAtomicLDW, ReadAtomicLDW]>;
  50. defm SC_W : AMO_rr_aq_rl<0b00011, 0b010, "sc.w">,
  51. Sched<[WriteAtomicSTW, ReadAtomicSTW, ReadAtomicSTW]>;
  52. defm AMOSWAP_W : AMO_rr_aq_rl<0b00001, 0b010, "amoswap.w">,
  53. Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;
  54. defm AMOADD_W : AMO_rr_aq_rl<0b00000, 0b010, "amoadd.w">,
  55. Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;
  56. defm AMOXOR_W : AMO_rr_aq_rl<0b00100, 0b010, "amoxor.w">,
  57. Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;
  58. defm AMOAND_W : AMO_rr_aq_rl<0b01100, 0b010, "amoand.w">,
  59. Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;
  60. defm AMOOR_W : AMO_rr_aq_rl<0b01000, 0b010, "amoor.w">,
  61. Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;
  62. defm AMOMIN_W : AMO_rr_aq_rl<0b10000, 0b010, "amomin.w">,
  63. Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;
  64. defm AMOMAX_W : AMO_rr_aq_rl<0b10100, 0b010, "amomax.w">,
  65. Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;
  66. defm AMOMINU_W : AMO_rr_aq_rl<0b11000, 0b010, "amominu.w">,
  67. Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;
  68. defm AMOMAXU_W : AMO_rr_aq_rl<0b11100, 0b010, "amomaxu.w">,
  69. Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;
  70. } // Predicates = [HasStdExtA]
  71. let Predicates = [HasStdExtA, IsRV64] in {
  72. defm LR_D : LR_r_aq_rl<0b011, "lr.d">, Sched<[WriteAtomicLDD, ReadAtomicLDD]>;
  73. defm SC_D : AMO_rr_aq_rl<0b00011, 0b011, "sc.d">,
  74. Sched<[WriteAtomicSTD, ReadAtomicSTD, ReadAtomicSTD]>;
  75. defm AMOSWAP_D : AMO_rr_aq_rl<0b00001, 0b011, "amoswap.d">,
  76. Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;
  77. defm AMOADD_D : AMO_rr_aq_rl<0b00000, 0b011, "amoadd.d">,
  78. Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;
  79. defm AMOXOR_D : AMO_rr_aq_rl<0b00100, 0b011, "amoxor.d">,
  80. Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;
  81. defm AMOAND_D : AMO_rr_aq_rl<0b01100, 0b011, "amoand.d">,
  82. Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;
  83. defm AMOOR_D : AMO_rr_aq_rl<0b01000, 0b011, "amoor.d">,
  84. Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;
  85. defm AMOMIN_D : AMO_rr_aq_rl<0b10000, 0b011, "amomin.d">,
  86. Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;
  87. defm AMOMAX_D : AMO_rr_aq_rl<0b10100, 0b011, "amomax.d">,
  88. Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;
  89. defm AMOMINU_D : AMO_rr_aq_rl<0b11000, 0b011, "amominu.d">,
  90. Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;
  91. defm AMOMAXU_D : AMO_rr_aq_rl<0b11100, 0b011, "amomaxu.d">,
  92. Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;
  93. } // Predicates = [HasStdExtA, IsRV64]
  94. //===----------------------------------------------------------------------===//
  95. // Pseudo-instructions and codegen patterns
  96. //===----------------------------------------------------------------------===//
  97. // Atomic load/store are available under both +a and +force-atomics.
  98. // Fences will be inserted for atomic load/stores according to the logic in
  99. // RISCVTargetLowering::{emitLeadingFence,emitTrailingFence}.
  100. let Predicates = [HasAtomicLdSt] in {
  101. defm : LdPat<atomic_load_8, LB>;
  102. defm : LdPat<atomic_load_16, LH>;
  103. defm : LdPat<atomic_load_32, LW>;
  104. defm : AtomicStPat<atomic_store_8, SB, GPR>;
  105. defm : AtomicStPat<atomic_store_16, SH, GPR>;
  106. defm : AtomicStPat<atomic_store_32, SW, GPR>;
  107. }
  108. let Predicates = [HasAtomicLdSt, IsRV64] in {
  109. defm : LdPat<atomic_load_64, LD, i64>;
  110. defm : AtomicStPat<atomic_store_64, SD, GPR, i64>;
  111. }
  112. let Predicates = [HasStdExtA] in {
  113. /// AMOs
  114. multiclass AMOPat<string AtomicOp, string BaseInst> {
  115. def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_monotonic"),
  116. !cast<RVInst>(BaseInst)>;
  117. def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_acquire"),
  118. !cast<RVInst>(BaseInst#"_AQ")>;
  119. def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_release"),
  120. !cast<RVInst>(BaseInst#"_RL")>;
  121. def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_acq_rel"),
  122. !cast<RVInst>(BaseInst#"_AQ_RL")>;
  123. def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_seq_cst"),
  124. !cast<RVInst>(BaseInst#"_AQ_RL")>;
  125. }
  126. defm : AMOPat<"atomic_swap_32", "AMOSWAP_W">;
  127. defm : AMOPat<"atomic_load_add_32", "AMOADD_W">;
  128. defm : AMOPat<"atomic_load_and_32", "AMOAND_W">;
  129. defm : AMOPat<"atomic_load_or_32", "AMOOR_W">;
  130. defm : AMOPat<"atomic_load_xor_32", "AMOXOR_W">;
  131. defm : AMOPat<"atomic_load_max_32", "AMOMAX_W">;
  132. defm : AMOPat<"atomic_load_min_32", "AMOMIN_W">;
  133. defm : AMOPat<"atomic_load_umax_32", "AMOMAXU_W">;
  134. defm : AMOPat<"atomic_load_umin_32", "AMOMINU_W">;
  135. def : Pat<(atomic_load_sub_32_monotonic GPR:$addr, GPR:$incr),
  136. (AMOADD_W GPR:$addr, (SUB X0, GPR:$incr))>;
  137. def : Pat<(atomic_load_sub_32_acquire GPR:$addr, GPR:$incr),
  138. (AMOADD_W_AQ GPR:$addr, (SUB X0, GPR:$incr))>;
  139. def : Pat<(atomic_load_sub_32_release GPR:$addr, GPR:$incr),
  140. (AMOADD_W_RL GPR:$addr, (SUB X0, GPR:$incr))>;
  141. def : Pat<(atomic_load_sub_32_acq_rel GPR:$addr, GPR:$incr),
  142. (AMOADD_W_AQ_RL GPR:$addr, (SUB X0, GPR:$incr))>;
  143. def : Pat<(atomic_load_sub_32_seq_cst GPR:$addr, GPR:$incr),
  144. (AMOADD_W_AQ_RL GPR:$addr, (SUB X0, GPR:$incr))>;
  145. /// Pseudo AMOs
  146. class PseudoAMO : Pseudo<(outs GPR:$res, GPR:$scratch),
  147. (ins GPR:$addr, GPR:$incr, ixlenimm:$ordering), []> {
  148. let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
  149. let mayLoad = 1;
  150. let mayStore = 1;
  151. let hasSideEffects = 0;
  152. }
  153. let Size = 20 in
  154. def PseudoAtomicLoadNand32 : PseudoAMO;
  155. // Ordering constants must be kept in sync with the AtomicOrdering enum in
  156. // AtomicOrdering.h.
  157. def : Pat<(atomic_load_nand_32_monotonic GPR:$addr, GPR:$incr),
  158. (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 2)>;
  159. def : Pat<(atomic_load_nand_32_acquire GPR:$addr, GPR:$incr),
  160. (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 4)>;
  161. def : Pat<(atomic_load_nand_32_release GPR:$addr, GPR:$incr),
  162. (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 5)>;
  163. def : Pat<(atomic_load_nand_32_acq_rel GPR:$addr, GPR:$incr),
  164. (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 6)>;
  165. def : Pat<(atomic_load_nand_32_seq_cst GPR:$addr, GPR:$incr),
  166. (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 7)>;
  167. class PseudoMaskedAMO
  168. : Pseudo<(outs GPR:$res, GPR:$scratch),
  169. (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$ordering), []> {
  170. let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
  171. let mayLoad = 1;
  172. let mayStore = 1;
  173. let hasSideEffects = 0;
  174. }
  175. class PseudoMaskedAMOMinMax
  176. : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),
  177. (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$sextshamt,
  178. ixlenimm:$ordering), []> {
  179. let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"
  180. "@earlyclobber $scratch2";
  181. let mayLoad = 1;
  182. let mayStore = 1;
  183. let hasSideEffects = 0;
  184. }
  185. class PseudoMaskedAMOUMinUMax
  186. : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),
  187. (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$ordering), []> {
  188. let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"
  189. "@earlyclobber $scratch2";
  190. let mayLoad = 1;
  191. let mayStore = 1;
  192. let hasSideEffects = 0;
  193. }
  194. class PseudoMaskedAMOPat<Intrinsic intrin, Pseudo AMOInst>
  195. : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering),
  196. (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>;
  197. class PseudoMaskedAMOMinMaxPat<Intrinsic intrin, Pseudo AMOInst>
  198. : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,
  199. timm:$ordering),
  200. (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,
  201. timm:$ordering)>;
  202. let Size = 28 in
  203. def PseudoMaskedAtomicSwap32 : PseudoMaskedAMO;
  204. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_xchg_i32,
  205. PseudoMaskedAtomicSwap32>;
  206. let Size = 28 in
  207. def PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAMO;
  208. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_add_i32,
  209. PseudoMaskedAtomicLoadAdd32>;
  210. let Size = 28 in
  211. def PseudoMaskedAtomicLoadSub32 : PseudoMaskedAMO;
  212. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_sub_i32,
  213. PseudoMaskedAtomicLoadSub32>;
  214. let Size = 32 in
  215. def PseudoMaskedAtomicLoadNand32 : PseudoMaskedAMO;
  216. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_nand_i32,
  217. PseudoMaskedAtomicLoadNand32>;
  218. let Size = 44 in
  219. def PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMOMinMax;
  220. def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_max_i32,
  221. PseudoMaskedAtomicLoadMax32>;
  222. let Size = 44 in
  223. def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMOMinMax;
  224. def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_min_i32,
  225. PseudoMaskedAtomicLoadMin32>;
  226. let Size = 36 in
  227. def PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMOUMinUMax;
  228. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umax_i32,
  229. PseudoMaskedAtomicLoadUMax32>;
  230. let Size = 36 in
  231. def PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMOUMinUMax;
  232. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umin_i32,
  233. PseudoMaskedAtomicLoadUMin32>;
  234. /// Compare and exchange
  235. class PseudoCmpXchg
  236. : Pseudo<(outs GPR:$res, GPR:$scratch),
  237. (ins GPR:$addr, GPR:$cmpval, GPR:$newval, ixlenimm:$ordering), []> {
  238. let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
  239. let mayLoad = 1;
  240. let mayStore = 1;
  241. let hasSideEffects = 0;
  242. let Size = 16;
  243. }
  244. // Ordering constants must be kept in sync with the AtomicOrdering enum in
  245. // AtomicOrdering.h.
  246. multiclass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst> {
  247. def : Pat<(!cast<PatFrag>(Op#"_monotonic") GPR:$addr, GPR:$cmp, GPR:$new),
  248. (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>;
  249. def : Pat<(!cast<PatFrag>(Op#"_acquire") GPR:$addr, GPR:$cmp, GPR:$new),
  250. (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>;
  251. def : Pat<(!cast<PatFrag>(Op#"_release") GPR:$addr, GPR:$cmp, GPR:$new),
  252. (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>;
  253. def : Pat<(!cast<PatFrag>(Op#"_acq_rel") GPR:$addr, GPR:$cmp, GPR:$new),
  254. (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>;
  255. def : Pat<(!cast<PatFrag>(Op#"_seq_cst") GPR:$addr, GPR:$cmp, GPR:$new),
  256. (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>;
  257. }
  258. def PseudoCmpXchg32 : PseudoCmpXchg;
  259. defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32>;
  260. def PseudoMaskedCmpXchg32
  261. : Pseudo<(outs GPR:$res, GPR:$scratch),
  262. (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask,
  263. ixlenimm:$ordering), []> {
  264. let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
  265. let mayLoad = 1;
  266. let mayStore = 1;
  267. let hasSideEffects = 0;
  268. let Size = 32;
  269. }
  270. def : Pat<(int_riscv_masked_cmpxchg_i32
  271. GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering),
  272. (PseudoMaskedCmpXchg32
  273. GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering)>;
  274. } // Predicates = [HasStdExtA]
  275. let Predicates = [HasStdExtA, IsRV64] in {
  276. defm : AMOPat<"atomic_swap_64", "AMOSWAP_D">;
  277. defm : AMOPat<"atomic_load_add_64", "AMOADD_D">;
  278. defm : AMOPat<"atomic_load_and_64", "AMOAND_D">;
  279. defm : AMOPat<"atomic_load_or_64", "AMOOR_D">;
  280. defm : AMOPat<"atomic_load_xor_64", "AMOXOR_D">;
  281. defm : AMOPat<"atomic_load_max_64", "AMOMAX_D">;
  282. defm : AMOPat<"atomic_load_min_64", "AMOMIN_D">;
  283. defm : AMOPat<"atomic_load_umax_64", "AMOMAXU_D">;
  284. defm : AMOPat<"atomic_load_umin_64", "AMOMINU_D">;
  285. /// 64-bit AMOs
  286. def : Pat<(i64 (atomic_load_sub_64_monotonic GPR:$addr, GPR:$incr)),
  287. (AMOADD_D GPR:$addr, (SUB X0, GPR:$incr))>;
  288. def : Pat<(i64 (atomic_load_sub_64_acquire GPR:$addr, GPR:$incr)),
  289. (AMOADD_D_AQ GPR:$addr, (SUB X0, GPR:$incr))>;
  290. def : Pat<(i64 (atomic_load_sub_64_release GPR:$addr, GPR:$incr)),
  291. (AMOADD_D_RL GPR:$addr, (SUB X0, GPR:$incr))>;
  292. def : Pat<(i64 (atomic_load_sub_64_acq_rel GPR:$addr, GPR:$incr)),
  293. (AMOADD_D_AQ_RL GPR:$addr, (SUB X0, GPR:$incr))>;
  294. def : Pat<(i64 (atomic_load_sub_64_seq_cst GPR:$addr, GPR:$incr)),
  295. (AMOADD_D_AQ_RL GPR:$addr, (SUB X0, GPR:$incr))>;
  296. /// 64-bit pseudo AMOs
  297. let Size = 20 in
  298. def PseudoAtomicLoadNand64 : PseudoAMO;
  299. // Ordering constants must be kept in sync with the AtomicOrdering enum in
  300. // AtomicOrdering.h.
  301. def : Pat<(i64 (atomic_load_nand_64_monotonic GPR:$addr, GPR:$incr)),
  302. (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 2)>;
  303. def : Pat<(i64 (atomic_load_nand_64_acquire GPR:$addr, GPR:$incr)),
  304. (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 4)>;
  305. def : Pat<(i64 (atomic_load_nand_64_release GPR:$addr, GPR:$incr)),
  306. (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 5)>;
  307. def : Pat<(i64 (atomic_load_nand_64_acq_rel GPR:$addr, GPR:$incr)),
  308. (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 6)>;
  309. def : Pat<(i64 (atomic_load_nand_64_seq_cst GPR:$addr, GPR:$incr)),
  310. (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 7)>;
  311. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_xchg_i64,
  312. PseudoMaskedAtomicSwap32>;
  313. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_add_i64,
  314. PseudoMaskedAtomicLoadAdd32>;
  315. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_sub_i64,
  316. PseudoMaskedAtomicLoadSub32>;
  317. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_nand_i64,
  318. PseudoMaskedAtomicLoadNand32>;
  319. def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_max_i64,
  320. PseudoMaskedAtomicLoadMax32>;
  321. def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_min_i64,
  322. PseudoMaskedAtomicLoadMin32>;
  323. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umax_i64,
  324. PseudoMaskedAtomicLoadUMax32>;
  325. def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umin_i64,
  326. PseudoMaskedAtomicLoadUMin32>;
  327. /// 64-bit compare and exchange
  328. def PseudoCmpXchg64 : PseudoCmpXchg;
  329. defm : PseudoCmpXchgPat<"atomic_cmp_swap_64", PseudoCmpXchg64>;
  330. def : Pat<(int_riscv_masked_cmpxchg_i64
  331. GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering),
  332. (PseudoMaskedCmpXchg32
  333. GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering)>;
  334. } // Predicates = [HasStdExtA, IsRV64]