1 //===-- RISCVInstrInfoZa.td - RISC-V Atomic instructions ---*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file describes the RISC-V instructions from the standard atomic 'Za*'
11 // - Zawrs (v1.0) : Wait-on-Reservation-Set.
12 // - Zacas (v1.0-rc1) : Atomic Compare-and-Swap.
14 //===----------------------------------------------------------------------===//
16 //===----------------------------------------------------------------------===//
17 // Zacas (Atomic Compare-and-Swap)
18 //===----------------------------------------------------------------------===//
20 def GPRPairRV32Operand : AsmOperandClass {
21 let Name = "GPRPairRV32";
22 let ParserMethod = "parseGPRPair<false>";
23 let PredicateMethod = "isGPRPair";
24 let RenderMethod = "addRegOperands";
27 def GPRPairRV64Operand : AsmOperandClass {
28 let Name = "GPRPairRV64";
29 let ParserMethod = "parseGPRPair<true>";
30 let PredicateMethod = "isGPRPair";
31 let RenderMethod = "addRegOperands";
34 def GPRPairRV32 : RegisterOperand<GPRPair> {
35 let ParserMatchClass = GPRPairRV32Operand;
38 def GPRPairRV64 : RegisterOperand<GPRPair> {
39 let ParserMatchClass = GPRPairRV64Operand;
42 let hasSideEffects = 0, mayLoad = 1, mayStore = 1, Constraints = "$rd = $rd_wb" in
43 class AMO_cas<bits<5> funct5, bit aq, bit rl, bits<3> funct3, string opcodestr,
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">;
49 multiclass AMO_cas_aq_rl<bits<5> funct5, bits<3> funct3, string opcodestr,
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>;
57 let Predicates = [HasStdExtZacas] in {
58 defm AMOCAS_W : AMO_cas_aq_rl<0b00101, 0b010, "amocas.w", GPR>;
59 } // Predicates = [HasStdExtZacas]
61 let Predicates = [HasStdExtZacas, IsRV32], DecoderNamespace = "RV32Zacas" in {
62 defm AMOCAS_D_RV32 : AMO_cas_aq_rl<0b00101, 0b011, "amocas.d", GPRPairRV32>;
63 } // Predicates = [HasStdExtZacas, IsRV32]
65 let Predicates = [HasStdExtZacas, IsRV64] in {
66 defm AMOCAS_D_RV64 : AMO_cas_aq_rl<0b00101, 0b011, "amocas.d", GPR>;
67 defm AMOCAS_Q : AMO_cas_aq_rl<0b00101, 0b100, "amocas.q", GPRPairRV64>;
68 } // Predicates = [HasStdExtZacas, IsRV64]
70 multiclass 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),
76 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
77 def : Pat<(!cast<PatFrag>(AtomicOp#"_acquire") (vt GPR:$addr),
80 (!cast<RVInst>(BaseInst#"_AQ") GPR:$cmp, GPR:$addr, GPR:$new)>;
81 def : Pat<(!cast<PatFrag>(AtomicOp#"_release") (vt GPR:$addr),
84 (!cast<RVInst>(BaseInst#"_RL") GPR:$cmp, GPR:$addr, GPR:$new)>;
85 def : Pat<(!cast<PatFrag>(AtomicOp#"_acq_rel") (vt GPR:$addr),
88 (!cast<RVInst>(BaseInst#"_AQ_RL") GPR:$cmp, GPR:$addr, GPR:$new)>;
89 def : Pat<(!cast<PatFrag>(AtomicOp#"_seq_cst") (vt GPR:$addr),
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),
98 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
99 def : Pat<(!cast<PatFrag>(AtomicOp#"_acquire") (vt GPR:$addr),
102 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
103 def : Pat<(!cast<PatFrag>(AtomicOp#"_release") (vt GPR:$addr),
106 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
107 def : Pat<(!cast<PatFrag>(AtomicOp#"_acq_rel") (vt GPR:$addr),
110 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
111 def : Pat<(!cast<PatFrag>(AtomicOp#"_seq_cst") (vt GPR:$addr),
114 (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
115 } // Predicates = !listconcat([HasStdExtZacas, HasStdExtZtso], ExtraPreds)
118 defm : AMOCASPat<"atomic_cmp_swap_32", "AMOCAS_W">;
119 defm : AMOCASPat<"atomic_cmp_swap_64", "AMOCAS_D_RV64", i64, [IsRV64]>;
121 //===----------------------------------------------------------------------===//
122 // Zawrs (Wait-on-Reservation-Set)
123 //===----------------------------------------------------------------------===//
125 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
126 class WRSInst<bits<12> funct12, string opcodestr>
127 : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), opcodestr, ""> {
133 let Predicates = [HasStdExtZawrs] in {
134 def WRS_NTO : WRSInst<0b000000001101, "wrs.nto">, Sched<[]>;
135 def WRS_STO : WRSInst<0b000000011101, "wrs.sto">, Sched<[]>;
136 } // Predicates = [HasStdExtZawrs]