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//===----------------------------------------------------------------------===// 15// Instruction class templates 16//===----------------------------------------------------------------------===// 17 18let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 19class LR_r<bit aq, bit rl, bits<3> funct3, string opcodestr> 20 : RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO, 21 (outs GPR:$rd), (ins GPRMemZeroOffset:$rs1), 22 opcodestr, "$rd, $rs1"> { 23 let rs2 = 0; 24} 25 26multiclass LR_r_aq_rl<bits<3> funct3, string opcodestr> { 27 def "" : LR_r<0, 0, funct3, opcodestr>; 28 def _AQ : LR_r<1, 0, funct3, opcodestr # ".aq">; 29 def _RL : LR_r<0, 1, funct3, opcodestr # ".rl">; 30 def _AQ_RL : LR_r<1, 1, funct3, opcodestr # ".aqrl">; 31} 32 33let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in 34class AMO_rr<bits<5> funct5, bit aq, bit rl, bits<3> funct3, string opcodestr> 35 : RVInstRAtomic<funct5, aq, rl, funct3, OPC_AMO, 36 (outs GPR:$rd), (ins GPRMemZeroOffset:$rs1, GPR:$rs2), 37 opcodestr, "$rd, $rs2, $rs1">; 38 39multiclass AMO_rr_aq_rl<bits<5> funct5, bits<3> funct3, string opcodestr> { 40 def "" : AMO_rr<funct5, 0, 0, funct3, opcodestr>; 41 def _AQ : AMO_rr<funct5, 1, 0, funct3, opcodestr # ".aq">; 42 def _RL : AMO_rr<funct5, 0, 1, funct3, opcodestr # ".rl">; 43 def _AQ_RL : AMO_rr<funct5, 1, 1, funct3, opcodestr # ".aqrl">; 44} 45 46//===----------------------------------------------------------------------===// 47// Instructions 48//===----------------------------------------------------------------------===// 49 50let Predicates = [HasStdExtA], IsSignExtendingOpW = 1 in { 51defm LR_W : LR_r_aq_rl<0b010, "lr.w">, Sched<[WriteAtomicLDW, ReadAtomicLDW]>; 52defm SC_W : AMO_rr_aq_rl<0b00011, 0b010, "sc.w">, 53 Sched<[WriteAtomicSTW, ReadAtomicSTW, ReadAtomicSTW]>; 54defm AMOSWAP_W : AMO_rr_aq_rl<0b00001, 0b010, "amoswap.w">, 55 Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>; 56defm AMOADD_W : AMO_rr_aq_rl<0b00000, 0b010, "amoadd.w">, 57 Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>; 58defm AMOXOR_W : AMO_rr_aq_rl<0b00100, 0b010, "amoxor.w">, 59 Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>; 60defm AMOAND_W : AMO_rr_aq_rl<0b01100, 0b010, "amoand.w">, 61 Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>; 62defm AMOOR_W : AMO_rr_aq_rl<0b01000, 0b010, "amoor.w">, 63 Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>; 64defm AMOMIN_W : AMO_rr_aq_rl<0b10000, 0b010, "amomin.w">, 65 Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>; 66defm AMOMAX_W : AMO_rr_aq_rl<0b10100, 0b010, "amomax.w">, 67 Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>; 68defm AMOMINU_W : AMO_rr_aq_rl<0b11000, 0b010, "amominu.w">, 69 Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>; 70defm AMOMAXU_W : AMO_rr_aq_rl<0b11100, 0b010, "amomaxu.w">, 71 Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>; 72} // Predicates = [HasStdExtA] 73 74let Predicates = [HasStdExtA, IsRV64] in { 75defm LR_D : LR_r_aq_rl<0b011, "lr.d">, Sched<[WriteAtomicLDD, ReadAtomicLDD]>; 76defm SC_D : AMO_rr_aq_rl<0b00011, 0b011, "sc.d">, 77 Sched<[WriteAtomicSTD, ReadAtomicSTD, ReadAtomicSTD]>; 78defm AMOSWAP_D : AMO_rr_aq_rl<0b00001, 0b011, "amoswap.d">, 79 Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>; 80defm AMOADD_D : AMO_rr_aq_rl<0b00000, 0b011, "amoadd.d">, 81 Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>; 82defm AMOXOR_D : AMO_rr_aq_rl<0b00100, 0b011, "amoxor.d">, 83 Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>; 84defm AMOAND_D : AMO_rr_aq_rl<0b01100, 0b011, "amoand.d">, 85 Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>; 86defm AMOOR_D : AMO_rr_aq_rl<0b01000, 0b011, "amoor.d">, 87 Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>; 88defm AMOMIN_D : AMO_rr_aq_rl<0b10000, 0b011, "amomin.d">, 89 Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>; 90defm AMOMAX_D : AMO_rr_aq_rl<0b10100, 0b011, "amomax.d">, 91 Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>; 92defm AMOMINU_D : AMO_rr_aq_rl<0b11000, 0b011, "amominu.d">, 93 Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>; 94defm AMOMAXU_D : AMO_rr_aq_rl<0b11100, 0b011, "amomaxu.d">, 95 Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>; 96} // Predicates = [HasStdExtA, IsRV64] 97 98//===----------------------------------------------------------------------===// 99// Pseudo-instructions and codegen patterns 100//===----------------------------------------------------------------------===// 101 102// Atomic load/store are available under both +a and +force-atomics. 103// Fences will be inserted for atomic load/stores according to the logic in 104// RISCVTargetLowering::{emitLeadingFence,emitTrailingFence}. 105let Predicates = [HasAtomicLdSt] in { 106 def : LdPat<atomic_load_8, LB>; 107 def : LdPat<atomic_load_16, LH>; 108 def : LdPat<atomic_load_32, LW>; 109 110 def : StPat<atomic_store_8, SB, GPR, XLenVT>; 111 def : StPat<atomic_store_16, SH, GPR, XLenVT>; 112 def : StPat<atomic_store_32, SW, GPR, XLenVT>; 113} 114 115let Predicates = [HasAtomicLdSt, IsRV64] in { 116 def : LdPat<atomic_load_64, LD, i64>; 117 def : StPat<atomic_store_64, SD, GPR, i64>; 118} 119 120/// AMOs 121 122multiclass AMOPat<string AtomicOp, string BaseInst, ValueType vt = XLenVT, 123 list<Predicate> ExtraPreds = []> { 124let Predicates = !listconcat([HasStdExtA, NotHasStdExtZtso], ExtraPreds) in { 125 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_monotonic"), 126 !cast<RVInst>(BaseInst), vt>; 127 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_acquire"), 128 !cast<RVInst>(BaseInst#"_AQ"), vt>; 129 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_release"), 130 !cast<RVInst>(BaseInst#"_RL"), vt>; 131 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_acq_rel"), 132 !cast<RVInst>(BaseInst#"_AQ_RL"), vt>; 133 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_seq_cst"), 134 !cast<RVInst>(BaseInst#"_AQ_RL"), vt>; 135} 136let Predicates = !listconcat([HasStdExtA, HasStdExtZtso], ExtraPreds) in { 137 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_monotonic"), 138 !cast<RVInst>(BaseInst), vt>; 139 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_acquire"), 140 !cast<RVInst>(BaseInst), vt>; 141 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_release"), 142 !cast<RVInst>(BaseInst), vt>; 143 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_acq_rel"), 144 !cast<RVInst>(BaseInst), vt>; 145 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_seq_cst"), 146 !cast<RVInst>(BaseInst), vt>; 147} 148} 149 150defm : AMOPat<"atomic_swap_32", "AMOSWAP_W">; 151defm : AMOPat<"atomic_load_add_32", "AMOADD_W">; 152defm : AMOPat<"atomic_load_and_32", "AMOAND_W">; 153defm : AMOPat<"atomic_load_or_32", "AMOOR_W">; 154defm : AMOPat<"atomic_load_xor_32", "AMOXOR_W">; 155defm : AMOPat<"atomic_load_max_32", "AMOMAX_W">; 156defm : AMOPat<"atomic_load_min_32", "AMOMIN_W">; 157defm : AMOPat<"atomic_load_umax_32", "AMOMAXU_W">; 158defm : AMOPat<"atomic_load_umin_32", "AMOMINU_W">; 159 160let Predicates = [HasStdExtA] in { 161 162/// Pseudo AMOs 163 164class PseudoAMO : Pseudo<(outs GPR:$res, GPR:$scratch), 165 (ins GPR:$addr, GPR:$incr, ixlenimm:$ordering), []> { 166 let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 167 let mayLoad = 1; 168 let mayStore = 1; 169 let hasSideEffects = 0; 170} 171 172let Size = 20 in 173def PseudoAtomicLoadNand32 : PseudoAMO; 174// Ordering constants must be kept in sync with the AtomicOrdering enum in 175// AtomicOrdering.h. 176def : Pat<(XLenVT (atomic_load_nand_32_monotonic GPR:$addr, GPR:$incr)), 177 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 2)>; 178def : Pat<(XLenVT (atomic_load_nand_32_acquire GPR:$addr, GPR:$incr)), 179 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 4)>; 180def : Pat<(XLenVT (atomic_load_nand_32_release GPR:$addr, GPR:$incr)), 181 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 5)>; 182def : Pat<(XLenVT (atomic_load_nand_32_acq_rel GPR:$addr, GPR:$incr)), 183 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 6)>; 184def : Pat<(XLenVT (atomic_load_nand_32_seq_cst GPR:$addr, GPR:$incr)), 185 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 7)>; 186 187class PseudoMaskedAMO 188 : Pseudo<(outs GPR:$res, GPR:$scratch), 189 (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$ordering), []> { 190 let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 191 let mayLoad = 1; 192 let mayStore = 1; 193 let hasSideEffects = 0; 194} 195 196class PseudoMaskedAMOMinMax 197 : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2), 198 (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$sextshamt, 199 ixlenimm:$ordering), []> { 200 let Constraints = "@earlyclobber $res,@earlyclobber $scratch1," 201 "@earlyclobber $scratch2"; 202 let mayLoad = 1; 203 let mayStore = 1; 204 let hasSideEffects = 0; 205} 206 207class PseudoMaskedAMOUMinUMax 208 : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2), 209 (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$ordering), []> { 210 let Constraints = "@earlyclobber $res,@earlyclobber $scratch1," 211 "@earlyclobber $scratch2"; 212 let mayLoad = 1; 213 let mayStore = 1; 214 let hasSideEffects = 0; 215} 216 217class PseudoMaskedAMOPat<Intrinsic intrin, Pseudo AMOInst> 218 : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering), 219 (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>; 220 221class PseudoMaskedAMOMinMaxPat<Intrinsic intrin, Pseudo AMOInst> 222 : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt, 223 timm:$ordering), 224 (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt, 225 timm:$ordering)>; 226 227let Size = 28 in 228def PseudoMaskedAtomicSwap32 : PseudoMaskedAMO; 229def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_xchg_i32, 230 PseudoMaskedAtomicSwap32>; 231let Size = 28 in 232def PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAMO; 233def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_add_i32, 234 PseudoMaskedAtomicLoadAdd32>; 235let Size = 28 in 236def PseudoMaskedAtomicLoadSub32 : PseudoMaskedAMO; 237def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_sub_i32, 238 PseudoMaskedAtomicLoadSub32>; 239let Size = 32 in 240def PseudoMaskedAtomicLoadNand32 : PseudoMaskedAMO; 241def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_nand_i32, 242 PseudoMaskedAtomicLoadNand32>; 243let Size = 44 in 244def PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMOMinMax; 245def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_max_i32, 246 PseudoMaskedAtomicLoadMax32>; 247let Size = 44 in 248def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMOMinMax; 249def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_min_i32, 250 PseudoMaskedAtomicLoadMin32>; 251let Size = 36 in 252def PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMOUMinUMax; 253def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umax_i32, 254 PseudoMaskedAtomicLoadUMax32>; 255let Size = 36 in 256def PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMOUMinUMax; 257def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umin_i32, 258 PseudoMaskedAtomicLoadUMin32>; 259 260/// Compare and exchange 261 262class PseudoCmpXchg 263 : Pseudo<(outs GPR:$res, GPR:$scratch), 264 (ins GPR:$addr, GPR:$cmpval, GPR:$newval, ixlenimm:$ordering), []> { 265 let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 266 let mayLoad = 1; 267 let mayStore = 1; 268 let hasSideEffects = 0; 269 let Size = 16; 270} 271 272// Ordering constants must be kept in sync with the AtomicOrdering enum in 273// AtomicOrdering.h. 274multiclass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst, 275 ValueType vt = XLenVT> { 276 def : Pat<(vt (!cast<PatFrag>(Op#"_monotonic") GPR:$addr, GPR:$cmp, GPR:$new)), 277 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>; 278 def : Pat<(vt (!cast<PatFrag>(Op#"_acquire") GPR:$addr, GPR:$cmp, GPR:$new)), 279 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>; 280 def : Pat<(vt (!cast<PatFrag>(Op#"_release") GPR:$addr, GPR:$cmp, GPR:$new)), 281 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>; 282 def : Pat<(vt (!cast<PatFrag>(Op#"_acq_rel") GPR:$addr, GPR:$cmp, GPR:$new)), 283 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>; 284 def : Pat<(vt (!cast<PatFrag>(Op#"_seq_cst") GPR:$addr, GPR:$cmp, GPR:$new)), 285 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>; 286} 287 288def PseudoCmpXchg32 : PseudoCmpXchg; 289defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32>; 290 291def PseudoMaskedCmpXchg32 292 : Pseudo<(outs GPR:$res, GPR:$scratch), 293 (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, 294 ixlenimm:$ordering), []> { 295 let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 296 let mayLoad = 1; 297 let mayStore = 1; 298 let hasSideEffects = 0; 299 let Size = 32; 300} 301 302def : Pat<(int_riscv_masked_cmpxchg_i32 303 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering), 304 (PseudoMaskedCmpXchg32 305 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering)>; 306 307} // Predicates = [HasStdExtA] 308 309defm : AMOPat<"atomic_swap_64", "AMOSWAP_D", i64, [IsRV64]>; 310defm : AMOPat<"atomic_load_add_64", "AMOADD_D", i64, [IsRV64]>; 311defm : AMOPat<"atomic_load_and_64", "AMOAND_D", i64, [IsRV64]>; 312defm : AMOPat<"atomic_load_or_64", "AMOOR_D", i64, [IsRV64]>; 313defm : AMOPat<"atomic_load_xor_64", "AMOXOR_D", i64, [IsRV64]>; 314defm : AMOPat<"atomic_load_max_64", "AMOMAX_D", i64, [IsRV64]>; 315defm : AMOPat<"atomic_load_min_64", "AMOMIN_D", i64, [IsRV64]>; 316defm : AMOPat<"atomic_load_umax_64", "AMOMAXU_D", i64, [IsRV64]>; 317defm : AMOPat<"atomic_load_umin_64", "AMOMINU_D", i64, [IsRV64]>; 318 319let Predicates = [HasStdExtA, IsRV64] in { 320 321/// 64-bit pseudo AMOs 322 323let Size = 20 in 324def PseudoAtomicLoadNand64 : PseudoAMO; 325// Ordering constants must be kept in sync with the AtomicOrdering enum in 326// AtomicOrdering.h. 327def : Pat<(i64 (atomic_load_nand_64_monotonic GPR:$addr, GPR:$incr)), 328 (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 2)>; 329def : Pat<(i64 (atomic_load_nand_64_acquire GPR:$addr, GPR:$incr)), 330 (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 4)>; 331def : Pat<(i64 (atomic_load_nand_64_release GPR:$addr, GPR:$incr)), 332 (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 5)>; 333def : Pat<(i64 (atomic_load_nand_64_acq_rel GPR:$addr, GPR:$incr)), 334 (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 6)>; 335def : Pat<(i64 (atomic_load_nand_64_seq_cst GPR:$addr, GPR:$incr)), 336 (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 7)>; 337 338def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_xchg_i64, 339 PseudoMaskedAtomicSwap32>; 340def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_add_i64, 341 PseudoMaskedAtomicLoadAdd32>; 342def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_sub_i64, 343 PseudoMaskedAtomicLoadSub32>; 344def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_nand_i64, 345 PseudoMaskedAtomicLoadNand32>; 346def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_max_i64, 347 PseudoMaskedAtomicLoadMax32>; 348def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_min_i64, 349 PseudoMaskedAtomicLoadMin32>; 350def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umax_i64, 351 PseudoMaskedAtomicLoadUMax32>; 352def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umin_i64, 353 PseudoMaskedAtomicLoadUMin32>; 354 355/// 64-bit compare and exchange 356 357def PseudoCmpXchg64 : PseudoCmpXchg; 358defm : PseudoCmpXchgPat<"atomic_cmp_swap_64", PseudoCmpXchg64, i64>; 359 360def : Pat<(int_riscv_masked_cmpxchg_i64 361 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering), 362 (PseudoMaskedCmpXchg32 363 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering)>; 364} // Predicates = [HasStdExtA, IsRV64] 365 366//===----------------------------------------------------------------------===// 367// Experimental RV64 i32 legalization patterns. 368//===----------------------------------------------------------------------===// 369 370class PatGprGprA<SDPatternOperator OpNode, RVInst Inst, ValueType vt> 371 : Pat<(vt (OpNode (XLenVT GPR:$rs1), (vt GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2)>; 372 373multiclass AMOPat2<string AtomicOp, string BaseInst, ValueType vt = XLenVT, 374 list<Predicate> ExtraPreds = []> { 375let Predicates = !listconcat([HasStdExtA, NotHasStdExtZtso], ExtraPreds) in { 376 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_monotonic"), 377 !cast<RVInst>(BaseInst), vt>; 378 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_acquire"), 379 !cast<RVInst>(BaseInst#"_AQ"), vt>; 380 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_release"), 381 !cast<RVInst>(BaseInst#"_RL"), vt>; 382 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_acq_rel"), 383 !cast<RVInst>(BaseInst#"_AQ_RL"), vt>; 384 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_seq_cst"), 385 !cast<RVInst>(BaseInst#"_AQ_RL"), vt>; 386} 387let Predicates = !listconcat([HasStdExtA, HasStdExtZtso], ExtraPreds) in { 388 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_monotonic"), 389 !cast<RVInst>(BaseInst), vt>; 390 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_acquire"), 391 !cast<RVInst>(BaseInst), vt>; 392 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_release"), 393 !cast<RVInst>(BaseInst), vt>; 394 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_acq_rel"), 395 !cast<RVInst>(BaseInst), vt>; 396 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_seq_cst"), 397 !cast<RVInst>(BaseInst), vt>; 398} 399} 400 401defm : AMOPat2<"atomic_swap_32", "AMOSWAP_W", i32>; 402defm : AMOPat2<"atomic_load_add_32", "AMOADD_W", i32>; 403defm : AMOPat2<"atomic_load_and_32", "AMOAND_W", i32>; 404defm : AMOPat2<"atomic_load_or_32", "AMOOR_W", i32>; 405defm : AMOPat2<"atomic_load_xor_32", "AMOXOR_W", i32>; 406defm : AMOPat2<"atomic_load_max_32", "AMOMAX_W", i32>; 407defm : AMOPat2<"atomic_load_min_32", "AMOMIN_W", i32>; 408defm : AMOPat2<"atomic_load_umax_32", "AMOMAXU_W", i32>; 409defm : AMOPat2<"atomic_load_umin_32", "AMOMINU_W", i32>; 410 411defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32, i32>; 412 413let Predicates = [HasAtomicLdSt] in { 414 def : LdPat<atomic_load_8, LB, i32>; 415 def : LdPat<atomic_load_16, LH, i32>; 416 def : LdPat<atomic_load_32, LW, i32>; 417 418 def : StPat<atomic_store_8, SB, GPR, i32>; 419 def : StPat<atomic_store_16, SH, GPR, i32>; 420 def : StPat<atomic_store_32, SW, GPR, i32>; 421} 422 423