1//===-- RISCVInstrInfoZa.td - RISC-V Atomic 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 atomic 'Za*' 10// extensions: 11// - Zawrs (v1.0) : Wait-on-Reservation-Set. 12// - Zacas (v1.0-rc1) : Atomic Compare-and-Swap. 13// 14//===----------------------------------------------------------------------===// 15 16//===----------------------------------------------------------------------===// 17// Zacas (Atomic Compare-and-Swap) 18//===----------------------------------------------------------------------===// 19 20def GPRPairRV32Operand : AsmOperandClass { 21 let Name = "GPRPairRV32"; 22 let ParserMethod = "parseGPRPair<false>"; 23 let PredicateMethod = "isGPRPair"; 24 let RenderMethod = "addRegOperands"; 25} 26 27def GPRPairRV64Operand : AsmOperandClass { 28 let Name = "GPRPairRV64"; 29 let ParserMethod = "parseGPRPair<true>"; 30 let PredicateMethod = "isGPRPair"; 31 let RenderMethod = "addRegOperands"; 32} 33 34def GPRPairRV32 : RegisterOperand<GPRPair> { 35 let ParserMatchClass = GPRPairRV32Operand; 36} 37 38def GPRPairRV64 : RegisterOperand<GPRPair> { 39 let ParserMatchClass = GPRPairRV64Operand; 40} 41 42let hasSideEffects = 0, mayLoad = 1, mayStore = 1, Constraints = "$rd = $rd_wb" in 43class AMO_cas<bits<5> funct5, bit aq, bit rl, bits<3> funct3, string opcodestr, 44 DAGOperand RC> 45 : RVInstRAtomic<funct5, aq, rl, funct3, OPC_AMO, 46 (outs RC:$rd_wb), (ins RC:$rd, GPRMemZeroOffset:$rs1, RC:$rs2), 47 opcodestr, "$rd, $rs2, $rs1">; 48 49multiclass AMO_cas_aq_rl<bits<5> funct5, bits<3> funct3, string opcodestr, 50 DAGOperand RC> { 51 def "" : AMO_cas<funct5, 0, 0, funct3, opcodestr, RC>; 52 def _AQ : AMO_cas<funct5, 1, 0, funct3, opcodestr # ".aq", RC>; 53 def _RL : AMO_cas<funct5, 0, 1, funct3, opcodestr # ".rl", RC>; 54 def _AQ_RL : AMO_cas<funct5, 1, 1, funct3, opcodestr # ".aqrl", RC>; 55} 56 57let Predicates = [HasStdExtZacas] in { 58defm AMOCAS_W : AMO_cas_aq_rl<0b00101, 0b010, "amocas.w", GPR>; 59} // Predicates = [HasStdExtZacas] 60 61let Predicates = [HasStdExtZacas, IsRV32], DecoderNamespace = "RV32Zacas" in { 62defm AMOCAS_D_RV32 : AMO_cas_aq_rl<0b00101, 0b011, "amocas.d", GPRPairRV32>; 63} // Predicates = [HasStdExtZacas, IsRV32] 64 65let Predicates = [HasStdExtZacas, IsRV64] in { 66defm AMOCAS_D_RV64 : AMO_cas_aq_rl<0b00101, 0b011, "amocas.d", GPR>; 67defm AMOCAS_Q : AMO_cas_aq_rl<0b00101, 0b100, "amocas.q", GPRPairRV64>; 68} // Predicates = [HasStdExtZacas, IsRV64] 69 70multiclass AMOCASPat<string AtomicOp, string BaseInst, ValueType vt = XLenVT, 71 list<Predicate> ExtraPreds = []> { 72 let Predicates = !listconcat([HasStdExtZacas, NotHasStdExtZtso], ExtraPreds) in { 73 def : Pat<(!cast<PatFrag>(AtomicOp#"_monotonic") (vt GPR:$addr), 74 (vt GPR:$cmp), 75 (vt GPR:$new)), 76 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>; 77 def : Pat<(!cast<PatFrag>(AtomicOp#"_acquire") (vt GPR:$addr), 78 (vt GPR:$cmp), 79 (vt GPR:$new)), 80 (!cast<RVInst>(BaseInst#"_AQ") GPR:$cmp, GPR:$addr, GPR:$new)>; 81 def : Pat<(!cast<PatFrag>(AtomicOp#"_release") (vt GPR:$addr), 82 (vt GPR:$cmp), 83 (vt GPR:$new)), 84 (!cast<RVInst>(BaseInst#"_RL") GPR:$cmp, GPR:$addr, GPR:$new)>; 85 def : Pat<(!cast<PatFrag>(AtomicOp#"_acq_rel") (vt GPR:$addr), 86 (vt GPR:$cmp), 87 (vt GPR:$new)), 88 (!cast<RVInst>(BaseInst#"_AQ_RL") GPR:$cmp, GPR:$addr, GPR:$new)>; 89 def : Pat<(!cast<PatFrag>(AtomicOp#"_seq_cst") (vt GPR:$addr), 90 (vt GPR:$cmp), 91 (vt GPR:$new)), 92 (!cast<RVInst>(BaseInst#"_AQ_RL") GPR:$cmp, GPR:$addr, GPR:$new)>; 93 } // Predicates = !listconcat([HasStdExtZacas, NotHasStdExtZtso], ExtraPreds) 94 let Predicates = !listconcat([HasStdExtZacas, HasStdExtZtso], ExtraPreds) in { 95 def : Pat<(!cast<PatFrag>(AtomicOp#"_monotonic") (vt GPR:$addr), 96 (vt GPR:$cmp), 97 (vt GPR:$new)), 98 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>; 99 def : Pat<(!cast<PatFrag>(AtomicOp#"_acquire") (vt GPR:$addr), 100 (vt GPR:$cmp), 101 (vt GPR:$new)), 102 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>; 103 def : Pat<(!cast<PatFrag>(AtomicOp#"_release") (vt GPR:$addr), 104 (vt GPR:$cmp), 105 (vt GPR:$new)), 106 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>; 107 def : Pat<(!cast<PatFrag>(AtomicOp#"_acq_rel") (vt GPR:$addr), 108 (vt GPR:$cmp), 109 (vt GPR:$new)), 110 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>; 111 def : Pat<(!cast<PatFrag>(AtomicOp#"_seq_cst") (vt GPR:$addr), 112 (vt GPR:$cmp), 113 (vt GPR:$new)), 114 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>; 115 } // Predicates = !listconcat([HasStdExtZacas, HasStdExtZtso], ExtraPreds) 116} 117 118defm : AMOCASPat<"atomic_cmp_swap_32", "AMOCAS_W">; 119defm : AMOCASPat<"atomic_cmp_swap_64", "AMOCAS_D_RV64", i64, [IsRV64]>; 120 121//===----------------------------------------------------------------------===// 122// Zawrs (Wait-on-Reservation-Set) 123//===----------------------------------------------------------------------===// 124 125let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 126class WRSInst<bits<12> funct12, string opcodestr> 127 : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), opcodestr, ""> { 128 let rs1 = 0; 129 let rd = 0; 130 let imm12 = funct12; 131} 132 133let Predicates = [HasStdExtZawrs] in { 134def WRS_NTO : WRSInst<0b000000001101, "wrs.nto">, Sched<[]>; 135def WRS_STO : WRSInst<0b000000011101, "wrs.sto">, Sched<[]>; 136} // Predicates = [HasStdExtZawrs] 137