brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.1 KiB · 5c81a09 Raw
474 lines · plain
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file describes the RISC-V instructions from the standard 'A', Atomic10// Instructions extension.11//12//===----------------------------------------------------------------------===//13 14//===----------------------------------------------------------------------===//15// Instruction class templates16//===----------------------------------------------------------------------===//17 18let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in19class 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 _AQRL : LR_r<1, 1, funct3, opcodestr # ".aqrl">;31}32 33let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in34class SC_r<bit aq, bit rl, bits<3> funct3, string opcodestr>35    : RVInstRAtomic<0b00011, aq, rl, funct3, OPC_AMO,36                    (outs GPR:$rd), (ins GPR:$rs2, GPRMemZeroOffset:$rs1),37                    opcodestr, "$rd, $rs2, $rs1">;38 39multiclass SC_r_aq_rl<bits<3> funct3, string opcodestr> {40  def ""    : SC_r<0, 0, funct3, opcodestr>;41  def _AQ   : SC_r<1, 0, funct3, opcodestr # ".aq">;42  def _RL   : SC_r<0, 1, funct3, opcodestr # ".rl">;43  def _AQRL : SC_r<1, 1, funct3, opcodestr # ".aqrl">;44}45 46let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in47class AMO_rr<bits<5> funct5, bit aq, bit rl, bits<3> funct3, string opcodestr>48    : RVInstRAtomic<funct5, aq, rl, funct3, OPC_AMO,49                    (outs GPR:$rd), (ins GPR:$rs2, GPRMemZeroOffset:$rs1),50                    opcodestr, "$rd, $rs2, $rs1">;51 52multiclass AMO_rr_aq_rl<bits<5> funct5, bits<3> funct3, string opcodestr> {53  def ""    : AMO_rr<funct5, 0, 0, funct3, opcodestr>;54  def _AQ   : AMO_rr<funct5, 1, 0, funct3, opcodestr # ".aq">;55  def _RL   : AMO_rr<funct5, 0, 1, funct3, opcodestr # ".rl">;56  def _AQRL : AMO_rr<funct5, 1, 1, funct3, opcodestr # ".aqrl">;57}58 59//===----------------------------------------------------------------------===//60// Instructions61//===----------------------------------------------------------------------===//62 63let Predicates = [HasStdExtZalrsc], IsSignExtendingOpW = 1 in {64defm LR_W       : LR_r_aq_rl<0b010, "lr.w">, Sched<[WriteAtomicLDW, ReadAtomicLDW]>;65defm SC_W       : SC_r_aq_rl<0b010, "sc.w">,66                  Sched<[WriteAtomicSTW, ReadAtomicSTW, ReadAtomicSTW]>;67} // Predicates = [HasStdExtZalrsc], IsSignExtendingOpW = 168 69let Predicates = [HasStdExtZaamo], IsSignExtendingOpW = 1 in {70defm AMOSWAP_W  : AMO_rr_aq_rl<0b00001, 0b010, "amoswap.w">,71                  Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;72defm AMOADD_W   : AMO_rr_aq_rl<0b00000, 0b010, "amoadd.w">,73                  Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;74defm AMOXOR_W   : AMO_rr_aq_rl<0b00100, 0b010, "amoxor.w">,75                  Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;76defm AMOAND_W   : AMO_rr_aq_rl<0b01100, 0b010, "amoand.w">,77                  Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;78defm AMOOR_W    : AMO_rr_aq_rl<0b01000, 0b010, "amoor.w">,79                  Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;80defm AMOMIN_W   : AMO_rr_aq_rl<0b10000, 0b010, "amomin.w">,81                  Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;82defm AMOMAX_W   : AMO_rr_aq_rl<0b10100, 0b010, "amomax.w">,83                  Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;84defm AMOMINU_W  : AMO_rr_aq_rl<0b11000, 0b010, "amominu.w">,85                  Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;86defm AMOMAXU_W  : AMO_rr_aq_rl<0b11100, 0b010, "amomaxu.w">,87                  Sched<[WriteAtomicW, ReadAtomicWA, ReadAtomicWD]>;88} // Predicates = [HasStdExtZaamo], IsSignExtendingOpW = 189 90let Predicates = [HasStdExtZalrsc, IsRV64] in {91defm LR_D       : LR_r_aq_rl<0b011, "lr.d">, Sched<[WriteAtomicLDD, ReadAtomicLDD]>;92defm SC_D       : SC_r_aq_rl<0b011, "sc.d">,93                  Sched<[WriteAtomicSTD, ReadAtomicSTD, ReadAtomicSTD]>;94} // Predicates = [HasStdExtZalrsc, IsRV64]95 96let Predicates = [HasStdExtZaamo, IsRV64] in {97defm AMOSWAP_D  : AMO_rr_aq_rl<0b00001, 0b011, "amoswap.d">,98                  Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;99defm AMOADD_D   : AMO_rr_aq_rl<0b00000, 0b011, "amoadd.d">,100                  Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;101defm AMOXOR_D   : AMO_rr_aq_rl<0b00100, 0b011, "amoxor.d">,102                  Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;103defm AMOAND_D   : AMO_rr_aq_rl<0b01100, 0b011, "amoand.d">,104                  Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;105defm AMOOR_D    : AMO_rr_aq_rl<0b01000, 0b011, "amoor.d">,106                  Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;107defm AMOMIN_D   : AMO_rr_aq_rl<0b10000, 0b011, "amomin.d">,108                  Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;109defm AMOMAX_D   : AMO_rr_aq_rl<0b10100, 0b011, "amomax.d">,110                  Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;111defm AMOMINU_D  : AMO_rr_aq_rl<0b11000, 0b011, "amominu.d">,112                  Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;113defm AMOMAXU_D  : AMO_rr_aq_rl<0b11100, 0b011, "amomaxu.d">,114                  Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;115} // Predicates = [HasStdExtZaamo, IsRV64]116 117//===----------------------------------------------------------------------===//118// Pseudo-instructions and codegen patterns119//===----------------------------------------------------------------------===//120 121let IsAtomic = 1 in {122// An atomic load operation that does not need either acquire or release123// semantics.124class relaxed_load<PatFrags base>125    : PatFrag<(ops node:$ptr), (base node:$ptr)> {126  let IsAtomicOrderingAcquireOrStronger = 0;127}128 129// A atomic load operation that actually needs acquire semantics.130class acquiring_load<PatFrags base>131    : PatFrag<(ops node:$ptr), (base node:$ptr)> {132  let IsAtomicOrderingAcquire = 1;133}134 135// An atomic load operation that needs sequential consistency.136class seq_cst_load<PatFrags base>137    : PatFrag<(ops node:$ptr), (base node:$ptr)> {138  let IsAtomicOrderingSequentiallyConsistent = 1;139}140 141// An atomic store operation that does not need either acquire or release142// semantics.143class relaxed_store<PatFrag base>144    : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr)> {145  let IsAtomicOrderingReleaseOrStronger = 0;146}147 148// A store operation that actually needs release semantics.149class releasing_store<PatFrag base>150    : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr)> {151  let IsAtomicOrderingRelease = 1;152}153 154// A store operation that actually needs sequential consistency.155class seq_cst_store<PatFrag base>156    : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr)> {157  let IsAtomicOrderingSequentiallyConsistent = 1;158}159} // IsAtomic = 1160 161// Atomic load/store are available under +zalrsc (thus also +a) and162// +force-atomics.  Fences will be inserted for atomic load/stores according to163// the logic in RISCVTargetLowering::{emitLeadingFence,emitTrailingFence}.164// The normal loads/stores are relaxed (unordered) loads/stores that don't have165// any ordering. This is necessary because AtomicExpandPass has added fences to166// atomic load/stores and changed them to unordered ones.167let Predicates = [HasAtomicLdSt] in {168  // Use unsigned for aext due to no c.lb in Zcb.169  def : LdPat<relaxed_load<atomic_load_sext_8>,   LB>;170  def : LdPat<relaxed_load<atomic_load_azext_8>,  LBU>;171  def : LdPat<relaxed_load<atomic_load_asext_16>, LH>;172  def : LdPat<relaxed_load<atomic_load_zext_16>,  LHU>;173 174  def : StPat<relaxed_store<atomic_store_8>,  SB, GPR, XLenVT>;175  def : StPat<relaxed_store<atomic_store_16>, SH, GPR, XLenVT>;176  def : StPat<relaxed_store<atomic_store_32>, SW, GPR, XLenVT>;177}178 179let Predicates = [HasAtomicLdSt, IsRV32] in {180  def : LdPat<relaxed_load<atomic_load_nonext_32>, LW, i32>;181}182 183let Predicates = [HasAtomicLdSt, IsRV64] in {184  def : LdPat<relaxed_load<atomic_load_asext_32>, LW, i64>;185  def : LdPat<relaxed_load<atomic_load_zext_32>, LWU, i64>;186  def : LdPat<relaxed_load<atomic_load_nonext_64>, LD, i64>;187  def : StPat<relaxed_store<atomic_store_64>, SD, GPR, i64>;188}189 190/// AMOs191 192class PatAMO<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>193    : Pat<(vt (OpNode (XLenVT GPR:$rs1), (vt GPR:$rs2))), (Inst GPR:$rs2, GPR:$rs1)>;194 195multiclass AMOPat<string AtomicOp, string BaseInst, ValueType vt = XLenVT,196                  list<Predicate> ExtraPreds = []> {197let Predicates = !listconcat([HasStdExtA, NoStdExtZtso], ExtraPreds) in {198  def : PatAMO<!cast<PatFrag>(AtomicOp#"_monotonic"),199               !cast<RVInst>(BaseInst), vt>;200  def : PatAMO<!cast<PatFrag>(AtomicOp#"_acquire"),201               !cast<RVInst>(BaseInst#"_AQ"), vt>;202  def : PatAMO<!cast<PatFrag>(AtomicOp#"_release"),203               !cast<RVInst>(BaseInst#"_RL"), vt>;204  def : PatAMO<!cast<PatFrag>(AtomicOp#"_acq_rel"),205               !cast<RVInst>(BaseInst#"_AQRL"), vt>;206  def : PatAMO<!cast<PatFrag>(AtomicOp#"_seq_cst"),207               !cast<RVInst>(BaseInst#"_AQRL"), vt>;208}209let Predicates = !listconcat([HasStdExtA, HasStdExtZtso], ExtraPreds) in {210  def : PatAMO<!cast<PatFrag>(AtomicOp#"_monotonic"),211               !cast<RVInst>(BaseInst), vt>;212  def : PatAMO<!cast<PatFrag>(AtomicOp#"_acquire"),213               !cast<RVInst>(BaseInst), vt>;214  def : PatAMO<!cast<PatFrag>(AtomicOp#"_release"),215               !cast<RVInst>(BaseInst), vt>;216  def : PatAMO<!cast<PatFrag>(AtomicOp#"_acq_rel"),217               !cast<RVInst>(BaseInst), vt>;218  def : PatAMO<!cast<PatFrag>(AtomicOp#"_seq_cst"),219               !cast<RVInst>(BaseInst), vt>;220}221}222 223defm : AMOPat<"atomic_swap_i32", "AMOSWAP_W">;224defm : AMOPat<"atomic_load_add_i32", "AMOADD_W">;225defm : AMOPat<"atomic_load_and_i32", "AMOAND_W">;226defm : AMOPat<"atomic_load_or_i32", "AMOOR_W">;227defm : AMOPat<"atomic_load_xor_i32", "AMOXOR_W">;228defm : AMOPat<"atomic_load_max_i32", "AMOMAX_W">;229defm : AMOPat<"atomic_load_min_i32", "AMOMIN_W">;230defm : AMOPat<"atomic_load_umax_i32", "AMOMAXU_W">;231defm : AMOPat<"atomic_load_umin_i32", "AMOMINU_W">;232 233defm : AMOPat<"atomic_swap_i64", "AMOSWAP_D", i64, [IsRV64]>;234defm : AMOPat<"atomic_load_add_i64", "AMOADD_D", i64, [IsRV64]>;235defm : AMOPat<"atomic_load_and_i64", "AMOAND_D", i64, [IsRV64]>;236defm : AMOPat<"atomic_load_or_i64", "AMOOR_D", i64, [IsRV64]>;237defm : AMOPat<"atomic_load_xor_i64", "AMOXOR_D", i64, [IsRV64]>;238defm : AMOPat<"atomic_load_max_i64", "AMOMAX_D", i64, [IsRV64]>;239defm : AMOPat<"atomic_load_min_i64", "AMOMIN_D", i64, [IsRV64]>;240defm : AMOPat<"atomic_load_umax_i64", "AMOMAXU_D", i64, [IsRV64]>;241defm : AMOPat<"atomic_load_umin_i64", "AMOMINU_D", i64, [IsRV64]>;242 243 244/// Pseudo AMOs245 246class PseudoAMO : Pseudo<(outs GPR:$res, GPR:$scratch),247                         (ins GPR:$addr, GPR:$incr, ixlenimm:$ordering), []> {248  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";249  let mayLoad = 1;250  let mayStore = 1;251  let hasSideEffects = 0;252}253 254class PseudoMaskedAMO255    : Pseudo<(outs GPR:$res, GPR:$scratch),256             (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$ordering), []> {257  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";258  let mayLoad = 1;259  let mayStore = 1;260  let hasSideEffects = 0;261}262 263class PseudoMaskedAMOMinMax264    : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),265             (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$sextshamt,266              ixlenimm:$ordering), []> {267  let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"268                    "@earlyclobber $scratch2";269  let mayLoad = 1;270  let mayStore = 1;271  let hasSideEffects = 0;272}273 274class PseudoMaskedAMOUMinUMax275    : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),276             (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$ordering), []> {277  let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"278                    "@earlyclobber $scratch2";279  let mayLoad = 1;280  let mayStore = 1;281  let hasSideEffects = 0;282}283 284// Ordering constants must be kept in sync with the AtomicOrdering enum in285// AtomicOrdering.h.286multiclass PseudoAMOPat<string AtomicOp, Pseudo AMOInst, ValueType vt = XLenVT> {287  def : Pat<(vt (!cast<PatFrag>(AtomicOp#"_monotonic") GPR:$addr, GPR:$incr)),288            (AMOInst GPR:$addr, GPR:$incr, 2)>;289  def : Pat<(vt (!cast<PatFrag>(AtomicOp#"_acquire") GPR:$addr, GPR:$incr)),290            (AMOInst GPR:$addr, GPR:$incr, 4)>;291  def : Pat<(vt (!cast<PatFrag>(AtomicOp#"_release") GPR:$addr, GPR:$incr)),292            (AMOInst GPR:$addr, GPR:$incr, 5)>;293  def : Pat<(vt (!cast<PatFrag>(AtomicOp#"_acq_rel") GPR:$addr, GPR:$incr)),294            (AMOInst GPR:$addr, GPR:$incr, 6)>;295  def : Pat<(vt (!cast<PatFrag>(AtomicOp#"_seq_cst") GPR:$addr, GPR:$incr)),296            (AMOInst GPR:$addr, GPR:$incr, 7)>;297}298 299class PseudoMaskedAMOPat<Intrinsic intrin, Pseudo AMOInst>300    : Pat<(XLenVT (intrin (XLenVT GPR:$addr), (XLenVT GPR:$incr),301                          (XLenVT GPR:$mask), (XLenVT timm:$ordering))),302          (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>;303 304class PseudoMaskedAMOMinMaxPat<Intrinsic intrin, Pseudo AMOInst>305    : Pat<(XLenVT (intrin (XLenVT GPR:$addr), (XLenVT GPR:$incr),306                          (XLenVT GPR:$mask), (XLenVT GPR:$shiftamt),307           (XLenVT timm:$ordering))),308          (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,309           timm:$ordering)>;310 311let Predicates = [HasStdExtZalrsc, NoStdExtZaamo] in {312 313let Size = 16 in {314def PseudoAtomicSwap32 : PseudoAMO;315def PseudoAtomicLoadAdd32 : PseudoAMO;316def PseudoAtomicLoadSub32 : PseudoAMO;317def PseudoAtomicLoadAnd32 : PseudoAMO;318def PseudoAtomicLoadOr32 : PseudoAMO;319def PseudoAtomicLoadXor32 : PseudoAMO;320} // Size = 16321let Size = 24 in {322def PseudoAtomicLoadMax32 : PseudoAMO;323def PseudoAtomicLoadMin32 : PseudoAMO;324def PseudoAtomicLoadUMax32 : PseudoAMO;325def PseudoAtomicLoadUMin32 : PseudoAMO;326} // Size = 24327 328defm : PseudoAMOPat<"atomic_swap_i32", PseudoAtomicSwap32>;329defm : PseudoAMOPat<"atomic_load_add_i32", PseudoAtomicLoadAdd32>;330defm : PseudoAMOPat<"atomic_load_sub_i32", PseudoAtomicLoadSub32>;331defm : PseudoAMOPat<"atomic_load_and_i32", PseudoAtomicLoadAnd32>;332defm : PseudoAMOPat<"atomic_load_or_i32", PseudoAtomicLoadOr32>;333defm : PseudoAMOPat<"atomic_load_xor_i32", PseudoAtomicLoadXor32>;334defm : PseudoAMOPat<"atomic_load_max_i32", PseudoAtomicLoadMax32>;335defm : PseudoAMOPat<"atomic_load_min_i32", PseudoAtomicLoadMin32>;336defm : PseudoAMOPat<"atomic_load_umax_i32", PseudoAtomicLoadUMax32>;337defm : PseudoAMOPat<"atomic_load_umin_i32", PseudoAtomicLoadUMin32>;338} // Predicates = [HasStdExtZalrsc, NoStdExtZaamo]339 340let Predicates = [HasStdExtZalrsc, NoStdExtZaamo, IsRV64] in {341 342let Size = 16 in {343def PseudoAtomicSwap64 : PseudoAMO;344def PseudoAtomicLoadAdd64 : PseudoAMO;345def PseudoAtomicLoadSub64 : PseudoAMO;346def PseudoAtomicLoadAnd64 : PseudoAMO;347def PseudoAtomicLoadOr64 : PseudoAMO;348def PseudoAtomicLoadXor64 : PseudoAMO;349} // Size = 16350let Size = 24 in {351def PseudoAtomicLoadMax64 : PseudoAMO;352def PseudoAtomicLoadMin64 : PseudoAMO;353def PseudoAtomicLoadUMax64 : PseudoAMO;354def PseudoAtomicLoadUMin64 : PseudoAMO;355} // Size = 24356 357defm : PseudoAMOPat<"atomic_swap_i64", PseudoAtomicSwap64, i64>;358defm : PseudoAMOPat<"atomic_load_add_i64", PseudoAtomicLoadAdd64, i64>;359defm : PseudoAMOPat<"atomic_load_sub_i64", PseudoAtomicLoadSub64, i64>;360defm : PseudoAMOPat<"atomic_load_and_i64", PseudoAtomicLoadAnd64, i64>;361defm : PseudoAMOPat<"atomic_load_or_i64", PseudoAtomicLoadOr64, i64>;362defm : PseudoAMOPat<"atomic_load_xor_i64", PseudoAtomicLoadXor64, i64>;363defm : PseudoAMOPat<"atomic_load_max_i64", PseudoAtomicLoadMax64, i64>;364defm : PseudoAMOPat<"atomic_load_min_i64", PseudoAtomicLoadMin64, i64>;365defm : PseudoAMOPat<"atomic_load_umax_i64", PseudoAtomicLoadUMax64, i64>;366defm : PseudoAMOPat<"atomic_load_umin_i64", PseudoAtomicLoadUMin64, i64>;367} // Predicates = [HasStdExtZalrsc, NoStdExtZaamo, IsRV64]368 369let Predicates = [HasStdExtZalrsc] in {370 371let Size = 20 in372def PseudoAtomicLoadNand32 : PseudoAMO;373defm : PseudoAMOPat<"atomic_load_nand_i32", PseudoAtomicLoadNand32>;374 375let Size = 28 in {376  def PseudoMaskedAtomicSwap32 : PseudoMaskedAMO;377  def PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAMO;378  def PseudoMaskedAtomicLoadSub32 : PseudoMaskedAMO;379}380let Size = 32 in {381  def PseudoMaskedAtomicLoadNand32 : PseudoMaskedAMO;382}383let Size = 44 in {384  def PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMOMinMax;385  def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMOMinMax;386}387let Size = 36 in {388 def PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMOUMinUMax;389 def PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMOUMinUMax;390}391 392def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_xchg,393                         PseudoMaskedAtomicSwap32>;394def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_add,395                         PseudoMaskedAtomicLoadAdd32>;396def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_sub,397                         PseudoMaskedAtomicLoadSub32>;398def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_nand,399                         PseudoMaskedAtomicLoadNand32>;400def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_max,401                               PseudoMaskedAtomicLoadMax32>;402def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_min,403                               PseudoMaskedAtomicLoadMin32>;404def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umax,405                         PseudoMaskedAtomicLoadUMax32>;406def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umin,407                         PseudoMaskedAtomicLoadUMin32>;408} // Predicates = [HasStdExtZalrsc]409 410let Predicates = [HasStdExtZalrsc, IsRV64] in {411 412let Size = 20 in413def PseudoAtomicLoadNand64 : PseudoAMO;414defm : PseudoAMOPat<"atomic_load_nand_i64", PseudoAtomicLoadNand64, i64>;415} // Predicates = [HasStdExtZalrsc, IsRV64]416 417 418/// Compare and exchange419 420class PseudoCmpXchg421    : Pseudo<(outs GPR:$res, GPR:$scratch),422             (ins GPR:$addr, GPR:$cmpval, GPR:$newval, ixlenimm:$ordering), []> {423  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";424  let mayLoad = 1;425  let mayStore = 1;426  let hasSideEffects = 0;427  let Size = 16;428}429 430// Ordering constants must be kept in sync with the AtomicOrdering enum in431// AtomicOrdering.h.432multiclass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst,433                            ValueType vt = XLenVT> {434  def : Pat<(vt (!cast<PatFrag>(Op#"_monotonic") GPR:$addr, GPR:$cmp, GPR:$new)),435            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>;436  def : Pat<(vt (!cast<PatFrag>(Op#"_acquire") GPR:$addr, GPR:$cmp, GPR:$new)),437            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>;438  def : Pat<(vt (!cast<PatFrag>(Op#"_release") GPR:$addr, GPR:$cmp, GPR:$new)),439            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>;440  def : Pat<(vt (!cast<PatFrag>(Op#"_acq_rel") GPR:$addr, GPR:$cmp, GPR:$new)),441            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>;442  def : Pat<(vt (!cast<PatFrag>(Op#"_seq_cst") GPR:$addr, GPR:$cmp, GPR:$new)),443            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>;444}445 446let Predicates = [HasStdExtZalrsc, NoStdExtZacas] in {447def PseudoCmpXchg32 : PseudoCmpXchg;448defm : PseudoCmpXchgPat<"atomic_cmp_swap_i32", PseudoCmpXchg32>;449}450 451let Predicates = [HasStdExtZalrsc, NoStdExtZacas, IsRV64] in {452def PseudoCmpXchg64 : PseudoCmpXchg;453defm : PseudoCmpXchgPat<"atomic_cmp_swap_i64", PseudoCmpXchg64, i64>;454}455 456let Predicates = [HasStdExtZalrsc] in {457def PseudoMaskedCmpXchg32458    : Pseudo<(outs GPR:$res, GPR:$scratch),459             (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask,460              ixlenimm:$ordering), []> {461  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";462  let mayLoad = 1;463  let mayStore = 1;464  let hasSideEffects = 0;465  let Size = 32;466}467 468def : Pat<(XLenVT (int_riscv_masked_cmpxchg469            (XLenVT GPR:$addr), (XLenVT GPR:$cmpval), (XLenVT GPR:$newval),470            (XLenVT GPR:$mask), (XLenVT timm:$ordering))),471          (PseudoMaskedCmpXchg32472            GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering)>;473} // Predicates = [HasStdExtZalrsc]474