blob: 9cb1d2f0b627d54987c34663aa73473e23549094 [file] [log] [blame]
Alex Bradbury8c345c52017-11-09 15:00:03 +00001//===-- RISCVInstrInfoA.td - RISC-V 'A' instructions -------*- tablegen -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the RISC-V instructions from the standard 'A', Atomic
11// Instructions extension.
12//
13//===----------------------------------------------------------------------===//
14
15//===----------------------------------------------------------------------===//
16// Instruction class templates
17//===----------------------------------------------------------------------===//
18
19let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
20class LR_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
21 : RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO,
22 (outs GPR:$rd), (ins GPR:$rs1),
23 opcodestr, "$rd, (${rs1})"> {
24 let rs2 = 0;
25}
26
27multiclass LR_r_aq_rl<bits<3> funct3, string opcodestr> {
28 def "" : LR_r<0, 0, funct3, opcodestr>;
29 def _AQ : LR_r<1, 0, funct3, opcodestr # ".aq">;
30 def _RL : LR_r<0, 1, funct3, opcodestr # ".rl">;
31 def _AQ_RL : LR_r<1, 1, funct3, opcodestr # ".aqrl">;
32}
33
34let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in
35class AMO_rr<bits<5> funct5, bit aq, bit rl, bits<3> funct3, string opcodestr>
36 : RVInstRAtomic<funct5, aq, rl, funct3, OPC_AMO,
37 (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),
38 opcodestr, "$rd, $rs2, (${rs1})">;
39
40multiclass AMO_rr_aq_rl<bits<5> funct5, bits<3> funct3, string opcodestr> {
41 def "" : AMO_rr<funct5, 0, 0, funct3, opcodestr>;
42 def _AQ : AMO_rr<funct5, 1, 0, funct3, opcodestr # ".aq">;
43 def _RL : AMO_rr<funct5, 0, 1, funct3, opcodestr # ".rl">;
44 def _AQ_RL : AMO_rr<funct5, 1, 1, funct3, opcodestr # ".aqrl">;
45}
46
Roger Ferrer Ibanezfe282172018-08-27 07:08:18 +000047multiclass AtomicStPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy> {
48 def : Pat<(StoreOp GPR:$rs1, StTy:$rs2), (Inst StTy:$rs2, GPR:$rs1, 0)>;
49 def : Pat<(StoreOp AddrFI:$rs1, StTy:$rs2), (Inst StTy:$rs2, AddrFI:$rs1, 0)>;
50 def : Pat<(StoreOp (add GPR:$rs1, simm12:$imm12), StTy:$rs2),
51 (Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>;
52 def : Pat<(StoreOp (add AddrFI:$rs1, simm12:$imm12), StTy:$rs2),
53 (Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
54 def : Pat<(StoreOp (IsOrAdd AddrFI:$rs1, simm12:$imm12), StTy:$rs2),
55 (Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
56}
57
Alex Bradbury8c345c52017-11-09 15:00:03 +000058//===----------------------------------------------------------------------===//
59// Instructions
60//===----------------------------------------------------------------------===//
61
62let Predicates = [HasStdExtA] in {
63defm LR_W : LR_r_aq_rl<0b010, "lr.w">;
64defm SC_W : AMO_rr_aq_rl<0b00011, 0b010, "sc.w">;
65defm AMOSWAP_W : AMO_rr_aq_rl<0b00001, 0b010, "amoswap.w">;
66defm AMOADD_W : AMO_rr_aq_rl<0b00000, 0b010, "amoadd.w">;
67defm AMOXOR_W : AMO_rr_aq_rl<0b00100, 0b010, "amoxor.w">;
68defm AMOAND_W : AMO_rr_aq_rl<0b01100, 0b010, "amoand.w">;
69defm AMOOR_W : AMO_rr_aq_rl<0b01000, 0b010, "amoor.w">;
70defm AMOMIN_W : AMO_rr_aq_rl<0b10000, 0b010, "amomin.w">;
71defm AMOMAX_W : AMO_rr_aq_rl<0b10100, 0b010, "amomax.w">;
72defm AMOMINU_W : AMO_rr_aq_rl<0b11000, 0b010, "amominu.w">;
73defm AMOMAXU_W : AMO_rr_aq_rl<0b11100, 0b010, "amomaxu.w">;
74} // Predicates = [HasStdExtA]
Alex Bradbury48f95a62017-12-07 10:59:12 +000075
76let Predicates = [HasStdExtA, IsRV64] in {
77defm LR_D : LR_r_aq_rl<0b011, "lr.d">;
78defm SC_D : AMO_rr_aq_rl<0b00011, 0b011, "sc.d">;
79defm AMOSWAP_D : AMO_rr_aq_rl<0b00001, 0b011, "amoswap.d">;
80defm AMOADD_D : AMO_rr_aq_rl<0b00000, 0b011, "amoadd.d">;
81defm AMOXOR_D : AMO_rr_aq_rl<0b00100, 0b011, "amoxor.d">;
82defm AMOAND_D : AMO_rr_aq_rl<0b01100, 0b011, "amoand.d">;
83defm AMOOR_D : AMO_rr_aq_rl<0b01000, 0b011, "amoor.d">;
84defm AMOMIN_D : AMO_rr_aq_rl<0b10000, 0b011, "amomin.d">;
85defm AMOMAX_D : AMO_rr_aq_rl<0b10100, 0b011, "amomax.d">;
86defm AMOMINU_D : AMO_rr_aq_rl<0b11000, 0b011, "amominu.d">;
87defm AMOMAXU_D : AMO_rr_aq_rl<0b11100, 0b011, "amomaxu.d">;
88} // Predicates = [HasStedExtA, IsRV64]
Alex Bradbury96f492d2018-06-13 12:04:51 +000089
90//===----------------------------------------------------------------------===//
91// Pseudo-instructions and codegen patterns
92//===----------------------------------------------------------------------===//
93
94let Predicates = [HasStdExtA] in {
95
96/// Atomic loads and stores
97
98// Fences will be inserted for atomic load/stores according to the logic in
99// RISCVTargetLowering::{emitLeadingFence,emitTrailingFence}.
100
101defm : LdPat<atomic_load_8, LB>;
102defm : LdPat<atomic_load_16, LH>;
103defm : LdPat<atomic_load_32, LW>;
104
Roger Ferrer Ibanezfe282172018-08-27 07:08:18 +0000105defm : AtomicStPat<atomic_store_8, SB, GPR>;
106defm : AtomicStPat<atomic_store_16, SH, GPR>;
107defm : AtomicStPat<atomic_store_32, SW, GPR>;
Alex Bradbury21aea512018-09-19 10:54:22 +0000108
109/// AMOs
110
111multiclass AMOPat<string AtomicOp, string BaseInst> {
112 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_monotonic"),
113 !cast<RVInst>(BaseInst)>;
114 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_acquire"),
115 !cast<RVInst>(BaseInst#"_AQ")>;
116 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_release"),
117 !cast<RVInst>(BaseInst#"_RL")>;
118 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_acq_rel"),
119 !cast<RVInst>(BaseInst#"_AQ_RL")>;
120 def : PatGprGpr<!cast<PatFrag>(AtomicOp#"_seq_cst"),
121 !cast<RVInst>(BaseInst#"_AQ_RL")>;
122}
123
124defm : AMOPat<"atomic_swap_32", "AMOSWAP_W">;
125defm : AMOPat<"atomic_load_add_32", "AMOADD_W">;
126defm : AMOPat<"atomic_load_and_32", "AMOAND_W">;
127defm : AMOPat<"atomic_load_or_32", "AMOOR_W">;
128defm : AMOPat<"atomic_load_xor_32", "AMOXOR_W">;
129defm : AMOPat<"atomic_load_max_32", "AMOMAX_W">;
130defm : AMOPat<"atomic_load_min_32", "AMOMIN_W">;
131defm : AMOPat<"atomic_load_umax_32", "AMOMAXU_W">;
132defm : AMOPat<"atomic_load_umin_32", "AMOMINU_W">;
133
134def : Pat<(atomic_load_sub_32_monotonic GPR:$addr, GPR:$incr),
135 (AMOADD_W GPR:$addr, (SUB X0, GPR:$incr))>;
136def : Pat<(atomic_load_sub_32_acquire GPR:$addr, GPR:$incr),
137 (AMOADD_W_AQ GPR:$addr, (SUB X0, GPR:$incr))>;
138def : Pat<(atomic_load_sub_32_release GPR:$addr, GPR:$incr),
139 (AMOADD_W_RL GPR:$addr, (SUB X0, GPR:$incr))>;
140def : Pat<(atomic_load_sub_32_acq_rel GPR:$addr, GPR:$incr),
141 (AMOADD_W_AQ_RL GPR:$addr, (SUB X0, GPR:$incr))>;
142def : Pat<(atomic_load_sub_32_seq_cst GPR:$addr, GPR:$incr),
143 (AMOADD_W_AQ_RL GPR:$addr, (SUB X0, GPR:$incr))>;
144
145/// Pseudo AMOs
146
147class PseudoAMO : Pseudo<(outs GPR:$res, GPR:$scratch),
Alex Bradburyd464ed82018-10-03 11:14:26 +0000148 (ins GPR:$addr, GPR:$incr, ixlenimm:$ordering), []> {
Alex Bradbury21aea512018-09-19 10:54:22 +0000149 let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
150 let mayLoad = 1;
151 let mayStore = 1;
152 let hasSideEffects = 0;
153}
154
155def PseudoAtomicLoadNand32 : PseudoAMO;
Alex Bradbury66d9a752018-11-29 20:43:42 +0000156// Ordering constants must be kept in sync with the AtomicOrdering enum in
Alex Bradbury21aea512018-09-19 10:54:22 +0000157// AtomicOrdering.h.
158def : Pat<(atomic_load_nand_32_monotonic GPR:$addr, GPR:$incr),
159 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 2)>;
160def : Pat<(atomic_load_nand_32_acquire GPR:$addr, GPR:$incr),
161 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 4)>;
162def : Pat<(atomic_load_nand_32_release GPR:$addr, GPR:$incr),
163 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 5)>;
164def : Pat<(atomic_load_nand_32_acq_rel GPR:$addr, GPR:$incr),
165 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 6)>;
166def : Pat<(atomic_load_nand_32_seq_cst GPR:$addr, GPR:$incr),
167 (PseudoAtomicLoadNand32 GPR:$addr, GPR:$incr, 7)>;
168
169class PseudoMaskedAMO
170 : Pseudo<(outs GPR:$res, GPR:$scratch),
Alex Bradburyd464ed82018-10-03 11:14:26 +0000171 (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$ordering), []> {
Alex Bradbury21aea512018-09-19 10:54:22 +0000172 let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
173 let mayLoad = 1;
174 let mayStore = 1;
175 let hasSideEffects = 0;
176}
177
178class PseudoMaskedAMOMinMax
179 : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),
Alex Bradburyd464ed82018-10-03 11:14:26 +0000180 (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$sextshamt,
181 ixlenimm:$ordering), []> {
Alex Bradbury21aea512018-09-19 10:54:22 +0000182 let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"
183 "@earlyclobber $scratch2";
184 let mayLoad = 1;
185 let mayStore = 1;
186 let hasSideEffects = 0;
187}
188
189class PseudoMaskedAMOUMinUMax
190 : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),
Alex Bradburyd464ed82018-10-03 11:14:26 +0000191 (ins GPR:$addr, GPR:$incr, GPR:$mask, ixlenimm:$ordering), []> {
Alex Bradbury21aea512018-09-19 10:54:22 +0000192 let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"
193 "@earlyclobber $scratch2";
194 let mayLoad = 1;
195 let mayStore = 1;
196 let hasSideEffects = 0;
197}
198
199class PseudoMaskedAMOPat<Intrinsic intrin, Pseudo AMOInst>
200 : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, imm:$ordering),
201 (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, imm:$ordering)>;
202
203class PseudoMaskedAMOMinMaxPat<Intrinsic intrin, Pseudo AMOInst>
204 : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,
205 imm:$ordering),
206 (AMOInst GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,
207 imm:$ordering)>;
208
209def PseudoMaskedAtomicSwap32 : PseudoMaskedAMO;
210def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_xchg_i32,
211 PseudoMaskedAtomicSwap32>;
212def PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAMO;
213def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_add_i32,
214 PseudoMaskedAtomicLoadAdd32>;
215def PseudoMaskedAtomicLoadSub32 : PseudoMaskedAMO;
216def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_sub_i32,
217 PseudoMaskedAtomicLoadSub32>;
218def PseudoMaskedAtomicLoadNand32 : PseudoMaskedAMO;
219def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_nand_i32,
220 PseudoMaskedAtomicLoadNand32>;
221def PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMOMinMax;
222def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_max_i32,
223 PseudoMaskedAtomicLoadMax32>;
224def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMOMinMax;
225def : PseudoMaskedAMOMinMaxPat<int_riscv_masked_atomicrmw_min_i32,
226 PseudoMaskedAtomicLoadMin32>;
227def PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMOUMinUMax;
228def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umax_i32,
229 PseudoMaskedAtomicLoadUMax32>;
230def PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMOUMinUMax;
231def : PseudoMaskedAMOPat<int_riscv_masked_atomicrmw_umin_i32,
232 PseudoMaskedAtomicLoadUMin32>;
Alex Bradbury66d9a752018-11-29 20:43:42 +0000233
234/// Compare and exchange
235
236class PseudoCmpXchg
237 : Pseudo<(outs GPR:$res, GPR:$scratch),
238 (ins GPR:$addr, GPR:$cmpval, GPR:$newval, i32imm:$ordering), []> {
239 let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
240 let mayLoad = 1;
241 let mayStore = 1;
242 let hasSideEffects = 0;
243}
244
245// Ordering constants must be kept in sync with the AtomicOrdering enum in
246// AtomicOrdering.h.
247multiclass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst> {
248 def : Pat<(!cast<PatFrag>(Op#"_monotonic") GPR:$addr, GPR:$cmp, GPR:$new),
249 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>;
250 def : Pat<(!cast<PatFrag>(Op#"_acquire") GPR:$addr, GPR:$cmp, GPR:$new),
251 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>;
252 def : Pat<(!cast<PatFrag>(Op#"_release") GPR:$addr, GPR:$cmp, GPR:$new),
253 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>;
254 def : Pat<(!cast<PatFrag>(Op#"_acq_rel") GPR:$addr, GPR:$cmp, GPR:$new),
255 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>;
256 def : Pat<(!cast<PatFrag>(Op#"_seq_cst") GPR:$addr, GPR:$cmp, GPR:$new),
257 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>;
258}
259
260def PseudoCmpXchg32 : PseudoCmpXchg;
261defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32>;
262
263def PseudoMaskedCmpXchg32
264 : Pseudo<(outs GPR:$res, GPR:$scratch),
265 (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask,
266 i32imm:$ordering), []> {
267 let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
268 let mayLoad = 1;
269 let mayStore = 1;
270 let hasSideEffects = 0;
271}
272
273def : Pat<(int_riscv_masked_cmpxchg_i32
274 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, imm:$ordering),
275 (PseudoMaskedCmpXchg32
276 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, imm:$ordering)>;
277
Roger Ferrer Ibanezfe282172018-08-27 07:08:18 +0000278} // Predicates = [HasStdExtA]