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 160defm : AMOPat<"atomic_swap_64", "AMOSWAP_D", i64, [IsRV64]>; 161defm : AMOPat<"atomic_load_add_64", "AMOADD_D", i64, [IsRV64]>; 162defm : AMOPat<"atomic_load_and_64", "AMOAND_D", i64, [IsRV64]>; 163defm : AMOPat<"atomic_load_or_64", "AMOOR_D", i64, [IsRV64]>; 164defm : AMOPat<"atomic_load_xor_64", "AMOXOR_D", i64, [IsRV64]>; 165defm : AMOPat<"atomic_load_max_64", "AMOMAX_D", i64, [IsRV64]>; 166defm : AMOPat<"atomic_load_min_64", "AMOMIN_D", i64, [IsRV64]>; 167defm : AMOPat<"atomic_load_umax_64", "AMOMAXU_D", i64, [IsRV64]>; 168defm : AMOPat<"atomic_load_umin_64", "AMOMINU_D", i64, [IsRV64]>; 169 170 171/// Pseudo AMOs 172 173class PseudoAMO : Pseudo<(outs GPR:$res, GPR:$scratch), 174 (ins GPR:$addr, GPR:$incr, ixlenimm:$ordering), []> { 175 let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 176 let mayLoad = 1; 177 let mayStore = 1; 178 let hasSideEffects = 0; 179} 180 181class PseudoMaskedAMO 182 : Pseudo<(outs GPR:$res, GPR:$scratch), 183 (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$ordering), []> { 184 let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 185 let mayLoad = 1; 186 let mayStore = 1; 187 let hasSideEffects = 0; 188} 189 190class PseudoMaskedAMOMinMax 191 : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2), 192 (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$sextshamt, 193 ixlenimm:$ordering), []> { 194 let Constraints = "@earlyclobber $res,@earlyclobber $scratch1," 195 "@earlyclobber $scratch2"; 196 let mayLoad = 1; 197 let mayStore = 1; 198 let hasSideEffects = 0; 199} 200 201class PseudoMaskedAMOUMinUMax 202 : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2), 203 (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$ordering), []> { 204 let Constraints = "@earlyclobber $res,@earlyclobber $scratch1," 205 "@earlyclobber $scratch2"; 206 let mayLoad = 1; 207 let mayStore = 1; 208 let hasSideEffects = 0; 209} 210 211class PseudoMaskedAMOPat<Intrinsic intrin, Pseudo AMOInst> 212 : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering), 213 (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>; 214 215class PseudoMaskedAMOMinMaxPat<Intrinsic intrin, Pseudo AMOInst> 216 : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt, 217 timm:$ordering), 218 (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt, 219 timm:$ordering)>; 220 221let Predicates = [HasStdExtA] in { 222 223let Size = 20 in 224def PseudoAtomicLoadNand32 : PseudoAMO; 225// Ordering constants must be kept in sync with the AtomicOrdering enum in 226// AtomicOrdering.h. 227def : Pat<(XLenVT (atomic_load_nand_32_monotonic GPR:$addr, GPR:$incr)), 228 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 2)>; 229def : Pat<(XLenVT (atomic_load_nand_32_acquire GPR:$addr, GPR:$incr)), 230 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 4)>; 231def : Pat<(XLenVT (atomic_load_nand_32_release GPR:$addr, GPR:$incr)), 232 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 5)>; 233def : Pat<(XLenVT (atomic_load_nand_32_acq_rel GPR:$addr, GPR:$incr)), 234 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 6)>; 235def : Pat<(XLenVT (atomic_load_nand_32_seq_cst GPR:$addr, GPR:$incr)), 236 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 7)>; 237 238let Size = 28 in 239def PseudoMaskedAtomicSwap32 : PseudoMaskedAMO; 240def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_xchg_i32, 241 PseudoMaskedAtomicSwap32>; 242let Size = 28 in 243def PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAMO; 244def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_add_i32, 245 PseudoMaskedAtomicLoadAdd32>; 246let Size = 28 in 247def PseudoMaskedAtomicLoadSub32 : PseudoMaskedAMO; 248def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_sub_i32, 249 PseudoMaskedAtomicLoadSub32>; 250let Size = 32 in 251def PseudoMaskedAtomicLoadNand32 : PseudoMaskedAMO; 252def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_nand_i32, 253 PseudoMaskedAtomicLoadNand32>; 254let Size = 44 in 255def PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMOMinMax; 256def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_max_i32, 257 PseudoMaskedAtomicLoadMax32>; 258let Size = 44 in 259def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMOMinMax; 260def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_min_i32, 261 PseudoMaskedAtomicLoadMin32>; 262let Size = 36 in 263def PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMOUMinUMax; 264def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umax_i32, 265 PseudoMaskedAtomicLoadUMax32>; 266let Size = 36 in 267def PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMOUMinUMax; 268def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umin_i32, 269 PseudoMaskedAtomicLoadUMin32>; 270} // Predicates = [HasStdExtA] 271 272let Predicates = [HasStdExtA, IsRV64] in { 273 274let Size = 20 in 275def PseudoAtomicLoadNand64 : PseudoAMO; 276// Ordering constants must be kept in sync with the AtomicOrdering enum in 277// AtomicOrdering.h. 278def : Pat<(i64 (atomic_load_nand_64_monotonic GPR:$addr, GPR:$incr)), 279 (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 2)>; 280def : Pat<(i64 (atomic_load_nand_64_acquire GPR:$addr, GPR:$incr)), 281 (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 4)>; 282def : Pat<(i64 (atomic_load_nand_64_release GPR:$addr, GPR:$incr)), 283 (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 5)>; 284def : Pat<(i64 (atomic_load_nand_64_acq_rel GPR:$addr, GPR:$incr)), 285 (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 6)>; 286def : Pat<(i64 (atomic_load_nand_64_seq_cst GPR:$addr, GPR:$incr)), 287 (PseudoAtomicLoadNand64 GPR:$addr, GPR:$incr, 7)>; 288 289def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_xchg_i64, 290 PseudoMaskedAtomicSwap32>; 291def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_add_i64, 292 PseudoMaskedAtomicLoadAdd32>; 293def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_sub_i64, 294 PseudoMaskedAtomicLoadSub32>; 295def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_nand_i64, 296 PseudoMaskedAtomicLoadNand32>; 297def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_max_i64, 298 PseudoMaskedAtomicLoadMax32>; 299def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_min_i64, 300 PseudoMaskedAtomicLoadMin32>; 301def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umax_i64, 302 PseudoMaskedAtomicLoadUMax32>; 303def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umin_i64, 304 PseudoMaskedAtomicLoadUMin32>; 305} // Predicates = [HasStdExtA, IsRV64] 306 307 308/// Compare and exchange 309 310class PseudoCmpXchg 311 : Pseudo<(outs GPR:$res, GPR:$scratch), 312 (ins GPR:$addr, GPR:$cmpval, GPR:$newval, ixlenimm:$ordering), []> { 313 let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 314 let mayLoad = 1; 315 let mayStore = 1; 316 let hasSideEffects = 0; 317 let Size = 16; 318} 319 320// Ordering constants must be kept in sync with the AtomicOrdering enum in 321// AtomicOrdering.h. 322multiclass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst, 323 ValueType vt = XLenVT> { 324 def : Pat<(vt (!cast<PatFrag>(Op#"_monotonic") GPR:$addr, GPR:$cmp, GPR:$new)), 325 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>; 326 def : Pat<(vt (!cast<PatFrag>(Op#"_acquire") GPR:$addr, GPR:$cmp, GPR:$new)), 327 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>; 328 def : Pat<(vt (!cast<PatFrag>(Op#"_release") GPR:$addr, GPR:$cmp, GPR:$new)), 329 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>; 330 def : Pat<(vt (!cast<PatFrag>(Op#"_acq_rel") GPR:$addr, GPR:$cmp, GPR:$new)), 331 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>; 332 def : Pat<(vt (!cast<PatFrag>(Op#"_seq_cst") GPR:$addr, GPR:$cmp, GPR:$new)), 333 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>; 334} 335 336let Predicates = [HasStdExtA, NoStdExtZacas] in { 337def PseudoCmpXchg32 : PseudoCmpXchg; 338defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32>; 339} 340 341let Predicates = [HasStdExtA, NoStdExtZacas, IsRV64] in { 342def PseudoCmpXchg64 : PseudoCmpXchg; 343defm : PseudoCmpXchgPat<"atomic_cmp_swap_64", PseudoCmpXchg64, i64>; 344} 345 346let Predicates = [HasStdExtA] in { 347def PseudoMaskedCmpXchg32 348 : Pseudo<(outs GPR:$res, GPR:$scratch), 349 (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, 350 ixlenimm:$ordering), []> { 351 let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 352 let mayLoad = 1; 353 let mayStore = 1; 354 let hasSideEffects = 0; 355 let Size = 32; 356} 357 358def : Pat<(int_riscv_masked_cmpxchg_i32 359 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering), 360 (PseudoMaskedCmpXchg32 361 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering)>; 362} // Predicates = [HasStdExtA] 363 364let Predicates = [HasStdExtA, IsRV64] in { 365def : Pat<(int_riscv_masked_cmpxchg_i64 366 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering), 367 (PseudoMaskedCmpXchg32 368 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering)>; 369} // Predicates = [HasStdExtA, IsRV64] 370 371//===----------------------------------------------------------------------===// 372// Experimental RV64 i32 legalization patterns. 373//===----------------------------------------------------------------------===// 374 375class PatGprGprA<SDPatternOperator OpNode, RVInst Inst, ValueType vt> 376 : Pat<(vt (OpNode (XLenVT GPR:$rs1), (vt GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2)>; 377 378multiclass AMOPat2<string AtomicOp, string BaseInst, ValueType vt = XLenVT, 379 list<Predicate> ExtraPreds = []> { 380let Predicates = !listconcat([HasStdExtA, NotHasStdExtZtso], ExtraPreds) in { 381 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_monotonic"), 382 !cast<RVInst>(BaseInst), vt>; 383 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_acquire"), 384 !cast<RVInst>(BaseInst#"_AQ"), vt>; 385 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_release"), 386 !cast<RVInst>(BaseInst#"_RL"), vt>; 387 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_acq_rel"), 388 !cast<RVInst>(BaseInst#"_AQ_RL"), vt>; 389 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_seq_cst"), 390 !cast<RVInst>(BaseInst#"_AQ_RL"), vt>; 391} 392let Predicates = !listconcat([HasStdExtA, HasStdExtZtso], ExtraPreds) in { 393 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_monotonic"), 394 !cast<RVInst>(BaseInst), vt>; 395 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_acquire"), 396 !cast<RVInst>(BaseInst), vt>; 397 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_release"), 398 !cast<RVInst>(BaseInst), vt>; 399 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_acq_rel"), 400 !cast<RVInst>(BaseInst), vt>; 401 def : PatGprGprA<!cast<PatFrag>(AtomicOp#"_seq_cst"), 402 !cast<RVInst>(BaseInst), vt>; 403} 404} 405 406defm : AMOPat2<"atomic_swap_32", "AMOSWAP_W", i32>; 407defm : AMOPat2<"atomic_load_add_32", "AMOADD_W", i32>; 408defm : AMOPat2<"atomic_load_and_32", "AMOAND_W", i32>; 409defm : AMOPat2<"atomic_load_or_32", "AMOOR_W", i32>; 410defm : AMOPat2<"atomic_load_xor_32", "AMOXOR_W", i32>; 411defm : AMOPat2<"atomic_load_max_32", "AMOMAX_W", i32>; 412defm : AMOPat2<"atomic_load_min_32", "AMOMIN_W", i32>; 413defm : AMOPat2<"atomic_load_umax_32", "AMOMAXU_W", i32>; 414defm : AMOPat2<"atomic_load_umin_32", "AMOMINU_W", i32>; 415 416let Predicates = [HasStdExtA, IsRV64] in 417defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32, i32>; 418 419let Predicates = [HasAtomicLdSt] in { 420 def : LdPat<atomic_load_8, LB, i32>; 421 def : LdPat<atomic_load_16, LH, i32>; 422 def : LdPat<atomic_load_32, LW, i32>; 423 424 def : StPat<atomic_store_8, SB, GPR, i32>; 425 def : StPat<atomic_store_16, SH, GPR, i32>; 426 def : StPat<atomic_store_32, SW, GPR, i32>; 427} 428 429