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