1//===-- RISCVInstrInfoXTHead.td ----------------------------*- 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 vendor extensions defined by T-Head of Alibaba.
10//
11//===----------------------------------------------------------------------===//
12
13//===----------------------------------------------------------------------===//
14// T-HEAD specific DAG Nodes.
15//===----------------------------------------------------------------------===//
16
17def SDT_LoadPair : SDTypeProfile<2, 2,
18  [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 3>, SDTCisPtrTy<2>, SDTCisVT<3, XLenVT>]>;
19def SDT_StorePair : SDTypeProfile<0, 4,
20  [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 3>, SDTCisPtrTy<2>, SDTCisVT<3, XLenVT>]>;
21
22def th_lwud : SDNode<"RISCVISD::TH_LWUD", SDT_LoadPair,
23  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
24def th_lwd : SDNode<"RISCVISD::TH_LWD", SDT_LoadPair,
25  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
26def th_ldd : SDNode<"RISCVISD::TH_LDD", SDT_LoadPair,
27  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
28def th_swd : SDNode<"RISCVISD::TH_SWD", SDT_StorePair,
29  [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
30def th_sdd : SDNode<"RISCVISD::TH_SDD", SDT_StorePair,
31  [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
32
33//===----------------------------------------------------------------------===//
34// Instruction class templates
35//===----------------------------------------------------------------------===//
36class THInstVdotVV<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
37                   string opcodestr, string argstr>
38    : RVInstVV<funct6, opv, outs, ins, opcodestr, argstr> {
39  let Inst{26} = 0;
40  let Inst{6-0} = OPC_CUSTOM_0.Value;
41  let DecoderNamespace = "THeadV";
42}
43
44class THInstVdotVX<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
45                   string opcodestr, string argstr>
46    : RVInstVX<funct6, opv, outs, ins, opcodestr, argstr> {
47  let Inst{26} = 1;
48  let Inst{6-0} = OPC_CUSTOM_0.Value;
49  let DecoderNamespace = "THeadV";
50}
51
52let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
53// op vd, vs1, vs2, vm (reverse the order of vs1 and vs2)
54class THVdotALUrVV<bits<6> funct6, RISCVVFormat opv, string opcodestr>
55    : THInstVdotVV<funct6, opv, (outs VR:$vd),
56                   (ins VR:$vs1, VR:$vs2, VMaskOp:$vm),
57                   opcodestr, "$vd, $vs1, $vs2$vm">;
58
59// op vd, rs1, vs2, vm (reverse the order of rs1 and vs2)
60class THVdotALUrVX<bits<6> funct6, RISCVVFormat opv, string opcodestr>
61    : THInstVdotVX<funct6, opv, (outs VR:$vd),
62                   (ins GPR:$rs1, VR:$vs2, VMaskOp:$vm),
63                   opcodestr, "$vd, $rs1, $vs2$vm">;
64} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
65
66let Predicates = [HasVendorXTHeadBa], DecoderNamespace = "THeadBa",
67  hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
68class THShiftALU_rri<bits<3> funct3, string opcodestr>
69    : RVInstR<0, funct3, OPC_CUSTOM_0, (outs GPR:$rd),
70              (ins GPR:$rs1, GPR:$rs2, uimm2:$uimm2),
71              opcodestr, "$rd, $rs1, $rs2, $uimm2"> {
72  bits<2> uimm2;
73  let Inst{31-27} = 0;
74  let Inst{26-25} = uimm2;
75}
76
77let Predicates = [HasVendorXTHeadBb], DecoderNamespace = "THeadBb",
78  hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
79class THShift_ri<bits<5> funct5, bits<3> funct3, string opcodestr>
80    : RVInstIShift<funct5, funct3, OPC_CUSTOM_0, (outs GPR:$rd),
81                   (ins GPR:$rs1, uimmlog2xlen:$shamt),
82                   opcodestr, "$rd, $rs1, $shamt">;
83
84class THBitfieldExtract_rii<bits<3> funct3, string opcodestr>
85    : RVInstI<funct3, OPC_CUSTOM_0, (outs GPR:$rd),
86              (ins GPR:$rs1, uimmlog2xlen:$msb, uimmlog2xlen:$lsb),
87              opcodestr, "$rd, $rs1, $msb, $lsb"> {
88  bits<6> msb;
89  bits<6> lsb;
90  let Inst{31-26} = msb;
91  let Inst{25-20} = lsb;
92}
93
94class THRev_r<bits<5> funct5, bits<2> funct2, string opcodestr>
95    : RVInstR4<funct2, 0b001, OPC_CUSTOM_0, (outs GPR:$rd), (ins GPR:$rs1),
96               opcodestr, "$rd, $rs1"> {
97  let rs3 = funct5;
98  let rs2 = 0;
99}
100}
101
102let Predicates = [HasVendorXTHeadBb, IsRV64], DecoderNamespace = "THeadBb",
103  hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
104class THShiftW_ri<bits<7> funct7, bits<3> funct3, string opcodestr>
105    : RVInstIShiftW<funct7, funct3, OPC_CUSTOM_0, (outs GPR:$rd),
106                    (ins GPR:$rs1, uimm5:$shamt),
107                    opcodestr, "$rd, $rs1, $shamt">;
108
109let Predicates = [HasVendorXTHeadCondMov], DecoderNamespace = "THeadCondMov",
110    hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in
111class THCondMov_rr<bits<7> funct7, string opcodestr>
112    : RVInstR<funct7, 0b001, OPC_CUSTOM_0, (outs GPR:$rd_wb),
113              (ins GPR:$rd, GPR:$rs1, GPR:$rs2),
114              opcodestr, "$rd, $rs1, $rs2"> {
115  let Constraints = "$rd_wb = $rd";
116}
117
118let Predicates = [HasVendorXTHeadMac], DecoderNamespace = "THeadMac",
119    hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in
120class THMulAccumulate_rr<bits<7> funct7, string opcodestr>
121    : RVInstR<funct7, 0b001, OPC_CUSTOM_0, (outs GPR:$rd_wb),
122              (ins GPR:$rd, GPR:$rs1, GPR:$rs2),
123              opcodestr, "$rd, $rs1, $rs2"> {
124  let Constraints = "$rd_wb = $rd";
125}
126
127let Predicates = [HasVendorXTHeadMemPair], DecoderNamespace = "THeadMemPair",
128  hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
129class THLoadPair<bits<5> funct5, string opcodestr>
130  : RVInstR<!shl(funct5, 2), 0b100, OPC_CUSTOM_0,
131            (outs GPR:$rd, GPR:$rs2),
132            (ins GPR:$rs1, uimm2:$uimm2, uimm7:$const3or4),
133             opcodestr, "$rd, $rs2, (${rs1}), $uimm2, $const3or4"> {
134  bits<2> uimm2;
135  let Inst{26-25} = uimm2;
136  let DecoderMethod = "decodeXTHeadMemPair";
137  let Constraints = "@earlyclobber $rd,@earlyclobber $rs2";
138}
139
140let Predicates = [HasVendorXTHeadMemPair], DecoderNamespace = "THeadMemPair",
141  hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
142class THStorePair<bits<5> funct5, string opcodestr>
143  : RVInstR<!shl(funct5, 2), 0b101, OPC_CUSTOM_0,
144            (outs),
145            (ins GPR:$rd, GPR:$rs2, GPR:$rs1, uimm2:$uimm2, uimm7:$const3or4),
146            opcodestr, "$rd, $rs2, (${rs1}), $uimm2, $const3or4"> {
147  bits<2> uimm2;
148  let Inst{26-25} = uimm2;
149  let DecoderMethod = "decodeXTHeadMemPair";
150}
151
152let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
153class THCacheInst_r<bits<5> funct5, string opcodestr>
154    : RVInstR<0b0000001, 0, OPC_CUSTOM_0, (outs), (ins GPR:$rs1),
155              opcodestr, "$rs1"> {
156  let rd = 0;
157  let rs2 = funct5;
158}
159
160let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
161class THCacheInst_rr<bits<7> funct7, string opcodestr>
162    : RVInstR<funct7, 0, OPC_CUSTOM_0, (outs), (ins GPR:$rs1, GPR:$rs2),
163      opcodestr, "$rs1, $rs2"> {
164  let rd = 0;
165}
166
167let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
168class THCacheInst_void<bits<5> funct5, string opcodestr>
169    : RVInstR<0b0000000, 0, OPC_CUSTOM_0, (outs), (ins), opcodestr, ""> {
170  let rd = 0;
171  let rs1 = 0;
172  let rs2 = funct5;
173}
174
175let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
176class THLoadIndexed<RegisterClass Ty, bits<5> funct5, string opcodestr>
177    : RVInstR<!shl(funct5, 2), !if(!eq(Ty, GPR), 0b100, 0b110), OPC_CUSTOM_0,
178              (outs Ty:$rd), (ins GPR:$rs1, GPR:$rs2, uimm2:$uimm2),
179              opcodestr, "$rd, $rs1, $rs2, $uimm2"> {
180  bits<2> uimm2;
181  let Inst{26-25} = uimm2;
182}
183
184class THLoadUpdate<bits<5> funct5, string opcodestr>
185    : RVInstI<0b100, OPC_CUSTOM_0, (outs GPR:$rd, GPR:$rs1_wb),
186              (ins GPR:$rs1, simm5:$simm5, uimm2:$uimm2),
187              opcodestr, "$rd, (${rs1}), $simm5, $uimm2"> {
188  bits<5> simm5;
189  bits<2> uimm2;
190  let imm12{11-7} = funct5;
191  let imm12{6-5} = uimm2;
192  let imm12{4-0} = simm5;
193  let Constraints = "@earlyclobber $rd, $rs1_wb = $rs1";
194}
195}
196
197let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
198class THStoreIndexed<RegisterClass StTy, bits<5> funct5, string opcodestr>
199    : RVInstR<!shl(funct5, 2), !if(!eq(StTy, GPR), 0b101, 0b111), OPC_CUSTOM_0,
200              (outs), (ins StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2),
201              opcodestr, "$rd, $rs1, $rs2, $uimm2"> {
202  bits<2> uimm2;
203  let Inst{26-25} = uimm2;
204}
205
206class THStoreUpdate<bits<5> funct5, string opcodestr>
207    : RVInstI<0b101, OPC_CUSTOM_0, (outs GPR:$rs1_up),
208              (ins GPR:$rd, GPR:$rs1, simm5:$simm5, uimm2:$uimm2),
209              opcodestr, "$rd, (${rs1}), $simm5, $uimm2"> {
210  bits<5> simm5;
211  bits<2> uimm2;
212  let imm12{11-7} = funct5;
213  let imm12{6-5} = uimm2;
214  let imm12{4-0} = simm5;
215  let Constraints = "$rs1_up = $rs1";
216}
217}
218
219//===----------------------------------------------------------------------===//
220// Combination of instruction classes.
221// Use these multiclasses to define instructions more easily.
222//===----------------------------------------------------------------------===//
223multiclass THVdotVMAQA_VX<string opcodestr, bits<6> funct6> {
224  def _VX : THVdotALUrVX<funct6, OPMVX, opcodestr # ".vx">;
225}
226
227multiclass THVdotVMAQA<string opcodestr, bits<6> funct6> {
228  def _VV   : THVdotALUrVV<funct6, OPMVX, opcodestr # ".vv">;
229  defm ""   : THVdotVMAQA_VX<opcodestr, funct6>;
230}
231
232//===----------------------------------------------------------------------===//
233// Instructions
234//===----------------------------------------------------------------------===//
235let Predicates = [HasVendorXTHeadBa] in {
236def TH_ADDSL : THShiftALU_rri<0b001, "th.addsl">,
237               Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
238} // Predicates = [HasVendorXTHeadBa]
239
240let Predicates = [HasVendorXTHeadBb] in {
241def TH_SRRI : THShift_ri<0b00010, 0b001, "th.srri">;
242def TH_EXT : THBitfieldExtract_rii<0b010, "th.ext">;
243def TH_EXTU : THBitfieldExtract_rii<0b011, "th.extu">;
244def TH_FF0 : THRev_r<0b10000, 0b10, "th.ff0">;
245def TH_FF1 : THRev_r<0b10000, 0b11, "th.ff1">;
246def TH_REV : THRev_r<0b10000, 0b01, "th.rev">;
247def TH_TSTNBZ : THRev_r<0b10000, 0b00, "th.tstnbz">;
248} // Predicates = [HasVendorXTHeadBb]
249
250let Predicates = [HasVendorXTHeadBb, IsRV64], IsSignExtendingOpW = 1 in {
251def TH_SRRIW : THShiftW_ri<0b0001010, 0b001, "th.srriw">;
252def TH_REVW : THRev_r<0b10010, 0b00, "th.revw">;
253} // Predicates = [HasVendorXTHeadBb, IsRV64]
254
255let Predicates = [HasVendorXTHeadBs], DecoderNamespace = "THeadBs" in {
256let IsSignExtendingOpW = 1 in
257def TH_TST : RVBShift_ri<0b10001, 0b001, OPC_CUSTOM_0, "th.tst">,
258             Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
259} // Predicates = [HasVendorXTHeadBs]
260
261let Predicates = [HasVendorXTHeadCondMov] in {
262def TH_MVEQZ  : THCondMov_rr<0b0100000, "th.mveqz">;
263def TH_MVNEZ  : THCondMov_rr<0b0100001, "th.mvnez">;
264} // Predicates = [HasVendorXTHeadCondMov]
265
266let Predicates = [HasVendorXTHeadMac] in {
267def TH_MULA  : THMulAccumulate_rr<0b0010000, "th.mula">;
268def TH_MULS  : THMulAccumulate_rr<0b0010001, "th.muls">;
269}  // Predicates = [HasVendorXTHeadMac]
270
271let Predicates = [HasVendorXTHeadMac], IsSignExtendingOpW = 1 in {
272def TH_MULAH : THMulAccumulate_rr<0b0010100, "th.mulah">;
273def TH_MULSH : THMulAccumulate_rr<0b0010101, "th.mulsh">;
274} // Predicates = [HasVendorXTHeadMac], IsSignExtendingOpW = 1
275
276let Predicates = [HasVendorXTHeadMac, IsRV64], IsSignExtendingOpW = 1 in {
277def TH_MULAW : THMulAccumulate_rr<0b0010010, "th.mulaw">;
278def TH_MULSW : THMulAccumulate_rr<0b0010011, "th.mulsw">;
279} // Predicates = [HasVendorXTHeadMac, IsRV64]
280
281let Predicates = [HasVendorXTHeadMemPair] in {
282def TH_LWUD : THLoadPair<0b11110, "th.lwud">,
283              Sched<[WriteLDW, WriteLDW, ReadMemBase]>;
284def TH_SWD  : THStorePair<0b11100, "th.swd">,
285              Sched<[WriteSTW, WriteSTW, ReadStoreData, ReadMemBase]>;
286let IsSignExtendingOpW = 1 in
287def TH_LWD  : THLoadPair<0b11100, "th.lwd">,
288              Sched<[WriteLDW, WriteLDW, ReadMemBase]>;
289}
290
291let Predicates = [HasVendorXTHeadMemPair, IsRV64] in {
292def TH_LDD  : THLoadPair<0b11111, "th.ldd">,
293              Sched<[WriteLDD, WriteLDD, ReadMemBase]>;
294def TH_SDD  : THStorePair<0b11111, "th.sdd">,
295              Sched<[WriteSTD, WriteSTD, ReadStoreData, ReadMemBase]>;
296}
297
298let Predicates = [HasVendorXTHeadMemIdx], DecoderNamespace = "THeadMemIdx" in {
299// T-Head Load/Store + Update instructions.
300def TH_LBIA : THLoadUpdate<0b00011, "th.lbia">,
301  Sched<[WriteLDB, ReadMemBase]>;
302def TH_LBIB : THLoadUpdate<0b00001, "th.lbib">,
303  Sched<[WriteLDB, ReadMemBase]>;
304def TH_LBUIA : THLoadUpdate<0b10011, "th.lbuia">,
305   Sched<[WriteLDB, ReadMemBase]>;
306def TH_LBUIB : THLoadUpdate<0b10001, "th.lbuib">,
307   Sched<[WriteLDB, ReadMemBase]>;
308
309def TH_LHIA : THLoadUpdate<0b00111, "th.lhia">,
310  Sched<[WriteLDH, ReadMemBase]>;
311def TH_LHIB : THLoadUpdate<0b00101, "th.lhib">,
312  Sched<[WriteLDH, ReadMemBase]>;
313def TH_LHUIA : THLoadUpdate<0b10111, "th.lhuia">,
314   Sched<[WriteLDH, ReadMemBase]>;
315def TH_LHUIB : THLoadUpdate<0b10101, "th.lhuib">,
316   Sched<[WriteLDH, ReadMemBase]>;
317
318def TH_LWIA : THLoadUpdate<0b01011, "th.lwia">,
319  Sched<[WriteLDW, ReadMemBase]>;
320def TH_LWIB : THLoadUpdate<0b01001, "th.lwib">,
321  Sched<[WriteLDW, ReadMemBase]>;
322
323def TH_SBIA : THStoreUpdate<0b00011, "th.sbia">,
324  Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
325def TH_SBIB : THStoreUpdate<0b00001, "th.sbib">,
326  Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
327
328def TH_SHIA : THStoreUpdate<0b00111, "th.shia">,
329  Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
330def TH_SHIB : THStoreUpdate<0b00101, "th.shib">,
331  Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
332
333def TH_SWIA : THStoreUpdate<0b01011, "th.swia">,
334  Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
335def TH_SWIB : THStoreUpdate<0b01001, "th.swib">,
336  Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
337
338// T-Head Load/Store Indexed instructions.
339def TH_LRB : THLoadIndexed<GPR, 0b00000, "th.lrb">,
340  Sched<[WriteLDB, ReadMemBase]>;
341def TH_LRBU : THLoadIndexed<GPR, 0b10000, "th.lrbu">,
342  Sched<[WriteLDB, ReadMemBase]>;
343def TH_LURB : THLoadIndexed<GPR, 0b00010, "th.lurb">,
344  Sched<[WriteLDB, ReadMemBase]>;
345def TH_LURBU : THLoadIndexed<GPR, 0b10010, "th.lurbu">,
346  Sched<[WriteLDB, ReadMemBase]>;
347
348def TH_LRH : THLoadIndexed<GPR, 0b00100, "th.lrh">,
349  Sched<[WriteLDH, ReadMemBase]>;
350def TH_LRHU : THLoadIndexed<GPR, 0b10100, "th.lrhu">,
351  Sched<[WriteLDH, ReadMemBase]>;
352def TH_LURH : THLoadIndexed<GPR, 0b00110, "th.lurh">,
353  Sched<[WriteLDB, ReadMemBase]>;
354def TH_LURHU : THLoadIndexed<GPR, 0b10110, "th.lurhu">,
355  Sched<[WriteLDB, ReadMemBase]>;
356
357def TH_LRW : THLoadIndexed<GPR, 0b01000, "th.lrw">,
358  Sched<[WriteLDW, ReadMemBase]>;
359def TH_LURW : THLoadIndexed<GPR, 0b01010, "th.lurw">,
360  Sched<[WriteLDB, ReadMemBase]>;
361
362def TH_SRB : THStoreIndexed<GPR, 0b00000, "th.srb">,
363  Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
364def TH_SURB : THStoreIndexed<GPR, 0b00010, "th.surb">,
365  Sched<[WriteLDB, ReadMemBase]>;
366
367def TH_SRH : THStoreIndexed<GPR, 0b00100, "th.srh">,
368  Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
369def TH_SURH : THStoreIndexed<GPR, 0b00110, "th.surh">,
370  Sched<[WriteLDB, ReadMemBase]>;
371
372def TH_SRW : THStoreIndexed<GPR, 0b01000, "th.srw">,
373  Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
374def TH_SURW : THStoreIndexed<GPR, 0b01010, "th.surw">,
375  Sched<[WriteLDB, ReadMemBase]>;
376}
377
378let Predicates = [HasVendorXTHeadMemIdx, IsRV64], DecoderNamespace = "THeadMemIdx" in {
379// T-Head Load/Store + Update instructions.
380def TH_LWUIA : THLoadUpdate<0b11011, "th.lwuia">,
381  Sched<[WriteLDH, ReadMemBase]>;
382def TH_LWUIB : THLoadUpdate<0b11001, "th.lwuib">,
383  Sched<[WriteLDH, ReadMemBase]>;
384
385def TH_LDIA : THLoadUpdate<0b01111, "th.ldia">,
386  Sched<[WriteLDW, ReadMemBase]>;
387def TH_LDIB : THLoadUpdate<0b01101, "th.ldib">,
388  Sched<[WriteLDW, ReadMemBase]>;
389
390def TH_SDIA : THStoreUpdate<0b01111, "th.sdia">,
391  Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
392def TH_SDIB : THStoreUpdate<0b01101, "th.sdib">,
393  Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
394
395// T-Head Load/Store Indexed instructions.
396def TH_LRWU : THLoadIndexed<GPR, 0b11000, "th.lrwu">,
397  Sched<[WriteLDW, ReadMemBase]>;
398def TH_LURWU : THLoadIndexed<GPR, 0b11010, "th.lurwu">,
399  Sched<[WriteLDB, ReadMemBase]>;
400
401def TH_LRD : THLoadIndexed<GPR, 0b01100, "th.lrd">,
402  Sched<[WriteLDW, ReadMemBase]>;
403def TH_LURD : THLoadIndexed<GPR, 0b01110, "th.lurd">,
404  Sched<[WriteLDB, ReadMemBase]>;
405
406def TH_SRD : THStoreIndexed<GPR, 0b01100, "th.srd">,
407  Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
408def TH_SURD : THStoreIndexed<GPR, 0b01110, "th.surd">,
409  Sched<[WriteLDB, ReadMemBase]>;
410}
411
412// T-Head Load/Store Indexed instructions for floating point registers.
413
414let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF],
415    DecoderNamespace = "THeadFMemIdx" in {
416def TH_FLRW : THLoadIndexed<FPR32, 0b01000, "th.flrw">,
417              Sched<[WriteFLD32, ReadFMemBase]>;
418def TH_FSRW : THStoreIndexed<FPR32, 0b01000, "th.fsrw">,
419              Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]>;
420}
421
422let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD],
423    DecoderNamespace = "THeadFMemIdx" in {
424def TH_FLRD : THLoadIndexed<FPR64, 0b01100, "th.flrd">,
425              Sched<[WriteFLD64, ReadFMemBase]>;
426def TH_FSRD : THStoreIndexed<FPR64, 0b01100, "th.fsrd">,
427              Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]>;
428}
429
430let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV64],
431    DecoderNamespace = "THeadFMemIdx" in {
432def TH_FLURW : THLoadIndexed<FPR32, 0b01010, "th.flurw">,
433               Sched<[WriteFLD32, ReadFMemBase]>;
434def TH_FSURW : THStoreIndexed<FPR32, 0b01010, "th.fsurw">,
435               Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]>;
436}
437
438let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV64],
439    DecoderNamespace = "THeadFMemIdx" in {
440def TH_FLURD : THLoadIndexed<FPR64, 0b01110, "th.flurd">,
441               Sched<[WriteFLD64, ReadFMemBase]>;
442def TH_FSURD : THStoreIndexed<FPR64, 0b01110, "th.fsurd">,
443               Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]>;
444}
445
446let Predicates = [HasVendorXTHeadVdot],
447    Constraints = "@earlyclobber $vd",
448    RVVConstraint = WidenV in {
449defm THVdotVMAQA      : THVdotVMAQA<"th.vmaqa",     0b100000>;
450defm THVdotVMAQAU     : THVdotVMAQA<"th.vmaqau",    0b100010>;
451defm THVdotVMAQASU    : THVdotVMAQA<"th.vmaqasu",   0b100100>;
452defm THVdotVMAQAUS    : THVdotVMAQA_VX<"th.vmaqaus",0b100110>;
453}
454
455// Associate LMUL with tablegen records of register classes.
456def THVdotV_M1  : LMULInfo<0b000,  8,   VR, VR,   VR,   VR,   VR, "M1">;
457def THVdotV_M2  : LMULInfo<0b001, 16, VRM2, VRM2, VR,   VR,   VR, "M2">;
458def THVdotV_M4  : LMULInfo<0b010, 32, VRM4, VRM4, VRM2, VR,   VR, "M4">;
459def THVdotV_M8  : LMULInfo<0b011, 64, VRM8, VRM8, VRM4, VRM2, VR, "M8">;
460
461defvar MxListTHVdot = [V_MF2, THVdotV_M1, THVdotV_M2, THVdotV_M4, THVdotV_M8];
462
463defset list<VTypeInfoToWide> AllQuadWidenableInt8NoVLMulVectors = {
464  def : VTypeInfoToWide<VI8MF2,  VI32MF2>;
465  def : VTypeInfoToWide<VI8M1,   VI32M1>;
466  def : VTypeInfoToWide<VI8M2,   VI32M2>;
467  def : VTypeInfoToWide<VI8M4,   VI32M4>;
468  def : VTypeInfoToWide<VI8M8,   VI32M8>;
469}
470
471//===----------------------------------------------------------------------===//
472// Combination of instruction classes.
473// Use these multiclasses to define instructions more easily.
474//===----------------------------------------------------------------------===//
475multiclass VPseudoVMAQA_VV_VX {
476  foreach m = MxListTHVdot in {
477    defm "" : VPseudoTernaryW_VV<m>;
478    defm "" : VPseudoTernaryW_VX<m>;
479  }
480}
481
482multiclass VPseudoVMAQA_VX {
483  foreach m = MxListTHVdot in {
484    defm "" : VPseudoTernaryW_VX<m>;
485  }
486}
487
488multiclass VPatTernaryVMAQA_VV<string intrinsic, string instruction,
489                               list<VTypeInfoToWide> vtilist> {
490  foreach vtiToWti = vtilist in {
491    defvar vti = vtiToWti.Vti;
492    defvar wti = vtiToWti.Wti;
493    defm : VPatTernaryWithPolicy<intrinsic, instruction, "VV",
494                                 wti.Vector, vti.Vector, vti.Vector,
495                                 vti.Mask, wti.Log2SEW, vti.LMul,
496                                 wti.RegClass, vti.RegClass, vti.RegClass>;
497  }
498}
499
500multiclass VPatTernaryVMAQA_VX<string intrinsic, string instruction,
501                               list<VTypeInfoToWide> vtilist> {
502  foreach vtiToWti = vtilist in {
503    defvar vti = vtiToWti.Vti;
504    defvar wti = vtiToWti.Wti;
505    defm : VPatTernaryWithPolicy<intrinsic, instruction,
506                                 "V"#vti.ScalarSuffix,
507                                 wti.Vector, vti.Scalar, vti.Vector,
508                                 vti.Mask, wti.Log2SEW, vti.LMul,
509                                 wti.RegClass, vti.ScalarRegClass, vti.RegClass>;
510  }
511}
512
513multiclass VPatTernaryVMAQA_VV_VX<string intrinsic, string instruction,
514                                  list<VTypeInfoToWide> vtilist>
515    : VPatTernaryVMAQA_VV<intrinsic, instruction, vtilist>,
516      VPatTernaryVMAQA_VX<intrinsic, instruction, vtilist>;
517
518//===----------------------------------------------------------------------===//
519// Pseudo-instructions and codegen patterns
520//===----------------------------------------------------------------------===//
521let Predicates = [HasVendorXTHeadBa] in {
522def : Pat<(add (XLenVT GPR:$rs1), (shl GPR:$rs2, uimm2:$uimm2)),
523          (TH_ADDSL GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
524
525// Reuse complex patterns from StdExtZba
526def : Pat<(add sh1add_op:$rs1, non_imm12:$rs2),
527          (TH_ADDSL GPR:$rs2, sh1add_op:$rs1, 1)>;
528def : Pat<(add sh2add_op:$rs1, non_imm12:$rs2),
529          (TH_ADDSL GPR:$rs2, sh2add_op:$rs1, 2)>;
530def : Pat<(add sh3add_op:$rs1, non_imm12:$rs2),
531          (TH_ADDSL GPR:$rs2, sh3add_op:$rs1, 3)>;
532
533def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 6)), GPR:$rs2),
534          (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 1), 1)>;
535def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 10)), GPR:$rs2),
536          (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 2), 1)>;
537def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 18)), GPR:$rs2),
538          (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 3), 1)>;
539def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 12)), GPR:$rs2),
540          (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 1), 2)>;
541def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 20)), GPR:$rs2),
542          (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 2), 2)>;
543def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 36)), GPR:$rs2),
544          (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 3), 2)>;
545def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 24)), GPR:$rs2),
546          (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 1), 3)>;
547def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 40)), GPR:$rs2),
548          (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 2), 3)>;
549def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 72)), GPR:$rs2),
550          (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 3), 3)>;
551
552def : Pat<(add (XLenVT GPR:$r), CSImm12MulBy4:$i),
553          (TH_ADDSL GPR:$r, (ADDI (XLenVT X0), (SimmShiftRightBy2XForm CSImm12MulBy4:$i)), 2)>;
554def : Pat<(add (XLenVT GPR:$r), CSImm12MulBy8:$i),
555          (TH_ADDSL GPR:$r, (ADDI (XLenVT X0), (SimmShiftRightBy3XForm CSImm12MulBy8:$i)), 3)>;
556
557def : Pat<(mul (XLenVT GPR:$r), C3LeftShift:$i),
558          (SLLI (TH_ADDSL GPR:$r, GPR:$r, 1),
559                (TrailingZeros C3LeftShift:$i))>;
560def : Pat<(mul (XLenVT GPR:$r), C5LeftShift:$i),
561          (SLLI (TH_ADDSL GPR:$r, GPR:$r, 2),
562                (TrailingZeros C5LeftShift:$i))>;
563def : Pat<(mul (XLenVT GPR:$r), C9LeftShift:$i),
564          (SLLI (TH_ADDSL GPR:$r, GPR:$r, 3),
565                (TrailingZeros C9LeftShift:$i))>;
566
567def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 11)),
568          (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 2), 1)>;
569def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 19)),
570          (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 3), 1)>;
571def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 13)),
572          (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 1), 2)>;
573def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 21)),
574          (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 2), 2)>;
575def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 37)),
576          (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 3), 2)>;
577def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 25)),
578          (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 2), (TH_ADDSL GPR:$r, GPR:$r, 2), 2)>;
579def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 41)),
580          (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 2), 3)>;
581def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 73)),
582          (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 3), 3)>;
583def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 27)),
584          (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 3), (TH_ADDSL GPR:$r, GPR:$r, 3), 1)>;
585def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 45)),
586          (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 3), (TH_ADDSL GPR:$r, GPR:$r, 3), 2)>;
587def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 81)),
588          (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 3), (TH_ADDSL GPR:$r, GPR:$r, 3), 3)>;
589
590def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 200)),
591          (SLLI (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 2),
592                          (TH_ADDSL GPR:$r, GPR:$r, 2), 2), 3)>;
593} // Predicates = [HasVendorXTHeadBa]
594
595let Predicates = [HasVendorXTHeadBb] in {
596def : PatGprImm<rotr, TH_SRRI, uimmlog2xlen>;
597// There's no encoding for a rotate-left-immediate in X-THead-Bb, as
598// it can be implemented with th.srri by negating the immediate.
599def : Pat<(rotl (XLenVT GPR:$rs1), uimmlog2xlen:$shamt),
600          (TH_SRRI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
601def : Pat<(sext_inreg (XLenVT GPR:$rs1), i32), (TH_EXT GPR:$rs1, 31, 0)>;
602def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (TH_EXT GPR:$rs1, 15, 0)>;
603def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (TH_EXT GPR:$rs1, 7, 0)>;
604def : Pat<(sext_inreg (XLenVT GPR:$rs1), i1), (TH_EXT GPR:$rs1, 0, 0)>;
605def : PatGpr<ctlz, TH_FF1>;
606def : Pat<(XLenVT (ctlz (xor (XLenVT GPR:$rs1), -1))), (TH_FF0 GPR:$rs1)>;
607def : PatGpr<bswap, TH_REV>;
608} // Predicates = [HasVendorXTHeadBb]
609
610let Predicates = [HasVendorXTHeadBb, IsRV64] in {
611def : PatGprImm<riscv_rorw, TH_SRRIW, uimm5>;
612def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
613          (TH_SRRIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
614def : Pat<(sra (bswap i64:$rs1), (i64 32)),
615          (TH_REVW i64:$rs1)>;
616def : Pat<(binop_allwusers<srl> (bswap i64:$rs1), (i64 32)),
617          (TH_REVW i64:$rs1)>;
618def : Pat<(riscv_clzw i64:$rs1),
619          (TH_FF0 (SLLI (XORI i64:$rs1, -1), 32))>;
620} // Predicates = [HasVendorXTHeadBb, IsRV64]
621
622let Predicates = [HasVendorXTHeadBs] in {
623def : Pat<(and (srl (XLenVT GPR:$rs1), uimmlog2xlen:$shamt), 1),
624          (TH_TST GPR:$rs1, uimmlog2xlen:$shamt)>;
625def : Pat<(XLenVT (seteq (and (XLenVT GPR:$rs1), SingleBitSetMask:$mask), 0)),
626          (TH_TST (XORI GPR:$rs1, -1), SingleBitSetMask:$mask)>;
627} // Predicates = [HasVendorXTHeadBs]
628
629let Predicates = [HasVendorXTHeadCondMov] in {
630def : Pat<(select (XLenVT GPR:$cond), (XLenVT GPR:$a), (XLenVT GPR:$b)),
631          (TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>;
632def : Pat<(select (XLenVT GPR:$cond), (XLenVT GPR:$a), (XLenVT 0)),
633          (TH_MVEQZ GPR:$a, (XLenVT X0), GPR:$cond)>;
634def : Pat<(select (XLenVT GPR:$cond), (XLenVT 0), (XLenVT GPR:$b)),
635          (TH_MVNEZ GPR:$b, (XLenVT X0), GPR:$cond)>;
636
637def : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT GPR:$b)),
638          (TH_MVNEZ GPR:$a, GPR:$b, GPR:$cond)>;
639def : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT GPR:$b)),
640          (TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>;
641def : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT 0)),
642          (TH_MVNEZ GPR:$a, (XLenVT X0), GPR:$cond)>;
643def : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT 0)),
644          (TH_MVEQZ GPR:$a, (XLenVT X0), GPR:$cond)>;
645def : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT 0), (XLenVT GPR:$b)),
646          (TH_MVEQZ GPR:$b, (XLenVT X0), GPR:$cond)>;
647def : Pat<(select (riscv_setne (XLenVT GPR:$cond)),  (XLenVT 0), (XLenVT GPR:$b)),
648          (TH_MVNEZ GPR:$b, (XLenVT X0), GPR:$cond)>;
649} // Predicates = [HasVendorXTHeadCondMov]
650
651let Predicates = [HasVendorXTHeadMac] in {
652def : Pat<(add GPR:$rd, (mul (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))),
653          (TH_MULA GPR:$rd, GPR:$rs1, GPR:$rs2)>;
654def : Pat<(sub GPR:$rd, (mul (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))),
655          (TH_MULS GPR:$rd, GPR:$rs1, GPR:$rs2)>;
656} // Predicates = [HasVendorXTHeadMac]
657
658let Predicates = [HasVendorXTHeadMac, IsRV64] in {
659// mulaw, mulsw are available only in RV64.
660def : Pat<(binop_allwusers<add> GPR:$rd, (mul GPR:$rs1, GPR:$rs2)),
661          (TH_MULAW GPR:$rd, GPR:$rs1, GPR:$rs2)>;
662def : Pat<(binop_allwusers<sub> GPR:$rd, (mul GPR:$rs1, GPR:$rs2)),
663          (TH_MULSW GPR:$rd, GPR:$rs1, GPR:$rs2)>;
664// mulah, mulsh produce a sign-extended result.
665def : Pat<(binop_allwusers<add> GPR:$rd, (mul
666            (sexti16 (i64 GPR:$rs1)),
667            (sexti16 (i64 GPR:$rs2)))),
668          (TH_MULAH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
669def : Pat<(binop_allwusers<sub> GPR:$rd, (mul
670            (sexti16 (i64 GPR:$rs1)),
671            (sexti16 (i64 GPR:$rs2)))),
672          (TH_MULSH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
673} // Predicates = [HasVendorXTHeadMac, IsRV64]
674
675let Predicates = [HasVendorXTHeadMac, IsRV32] in {
676def : Pat<(i32 (add GPR:$rd, (mul (sexti16 (i32 GPR:$rs1)),
677                                  (sexti16 (i32 GPR:$rs2))))),
678          (TH_MULAH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
679def : Pat<(i32 (sub GPR:$rd, (mul (sexti16 (i32 GPR:$rs1)),
680                                  (sexti16 (i32 GPR:$rs2))))),
681          (TH_MULSH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
682} // Predicates = [HasVendorXTHeadMac, IsRV32]
683
684defm PseudoTHVdotVMAQA      : VPseudoVMAQA_VV_VX;
685defm PseudoTHVdotVMAQAU     : VPseudoVMAQA_VV_VX;
686defm PseudoTHVdotVMAQASU    : VPseudoVMAQA_VV_VX;
687defm PseudoTHVdotVMAQAUS    : VPseudoVMAQA_VX;
688
689let Predicates = [HasVendorXTHeadVdot] in {
690defm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqa",  "PseudoTHVdotVMAQA",  AllQuadWidenableInt8NoVLMulVectors>;
691defm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqau", "PseudoTHVdotVMAQAU", AllQuadWidenableInt8NoVLMulVectors>;
692defm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqasu","PseudoTHVdotVMAQASU",AllQuadWidenableInt8NoVLMulVectors>;
693defm : VPatTernaryVMAQA_VX<"int_riscv_th_vmaqaus",   "PseudoTHVdotVMAQAUS",AllQuadWidenableInt8NoVLMulVectors>;
694}
695
696def uimm2_3_XFORM : SDNodeXForm<imm, [{
697  return CurDAG->getTargetConstant((N->getZExtValue() >> 3) & 0x3,
698                                   SDLoc(N), Subtarget->getXLenVT());
699}]>;
700
701def uimm2_3 : Operand<XLenVT>, ImmLeaf<XLenVT, [{
702  return isShiftedUInt<2, 3>(Imm);
703}], uimm2_3_XFORM>;
704
705def uimm2_4_XFORM : SDNodeXForm<imm, [{
706  return CurDAG->getTargetConstant((N->getZExtValue() >> 4) & 0x3,
707                                   SDLoc(N), Subtarget->getXLenVT());
708}]>;
709
710def uimm2_4 : Operand<XLenVT>, ImmLeaf<XLenVT, [{
711  return isShiftedUInt<2, 4>(Imm);
712}], uimm2_4_XFORM>;
713
714let Predicates = [HasVendorXTHeadMemPair, IsRV64] in {
715def : Pat<(th_lwud i64:$rs1, uimm2_3:$uimm2_3), (TH_LWUD i64:$rs1, uimm2_3:$uimm2_3, 3)>;
716def : Pat<(th_ldd i64:$rs1, uimm2_4:$uimm2_4), (TH_LDD i64:$rs1, uimm2_4:$uimm2_4, 4)>;
717
718def : Pat<(th_sdd i64:$rd1, i64:$rd2, i64:$rs1, uimm2_4:$uimm2_4),
719          (TH_SDD i64:$rd1, i64:$rd2, i64:$rs1, uimm2_4:$uimm2_4, 4)>;
720}
721
722let Predicates = [HasVendorXTHeadMemPair] in {
723  def : Pat<(th_lwd GPR:$rs1, uimm2_3:$uimm2_3), (TH_LWD GPR:$rs1, uimm2_3:$uimm2_3, 3)>;
724  def : Pat<(th_swd GPR:$rd1, GPR:$rd2, GPR:$rs1, uimm2_3:$uimm2_3),
725            (TH_SWD GPR:$rd1, GPR:$rd2, GPR:$rs1, uimm2_3:$uimm2_3, 3)>;
726}
727
728let Predicates = [HasVendorXTHeadCmo], DecoderNamespace = "THeadCmo" in {
729def TH_DCACHE_CSW    : THCacheInst_r<0b00001, "th.dcache.csw">;
730def TH_DCACHE_ISW    : THCacheInst_r<0b00010, "th.dcache.isw">;
731def TH_DCACHE_CISW   : THCacheInst_r<0b00011, "th.dcache.cisw">;
732def TH_DCACHE_CVAL1  : THCacheInst_r<0b00100, "th.dcache.cval1">;
733def TH_DCACHE_CVA    : THCacheInst_r<0b00101, "th.dcache.cva">;
734def TH_DCACHE_IVA    : THCacheInst_r<0b00110, "th.dcache.iva">;
735def TH_DCACHE_CIVA   : THCacheInst_r<0b00111, "th.dcache.civa">;
736def TH_DCACHE_CPAL1  : THCacheInst_r<0b01000, "th.dcache.cpal1">;
737def TH_DCACHE_CPA    : THCacheInst_r<0b01001, "th.dcache.cpa">;
738def TH_DCACHE_IPA    : THCacheInst_r<0b01010, "th.dcache.ipa">;
739def TH_DCACHE_CIPA   : THCacheInst_r<0b01011, "th.dcache.cipa">;
740def TH_ICACHE_IVA    : THCacheInst_r<0b10000, "th.icache.iva">;
741def TH_ICACHE_IPA    : THCacheInst_r<0b11000, "th.icache.ipa">;
742
743def TH_DCACHE_CALL   : THCacheInst_void<0b00001, "th.dcache.call">;
744def TH_DCACHE_IALL   : THCacheInst_void<0b00010, "th.dcache.iall">;
745def TH_DCACHE_CIALL  : THCacheInst_void<0b00011, "th.dcache.ciall">;
746def TH_ICACHE_IALL   : THCacheInst_void<0b10000, "th.icache.iall">;
747def TH_ICACHE_IALLS  : THCacheInst_void<0b10001, "th.icache.ialls">;
748def TH_L2CACHE_CALL  : THCacheInst_void<0b10101, "th.l2cache.call">;
749def TH_L2CACHE_IALL  : THCacheInst_void<0b10110, "th.l2cache.iall">;
750def TH_L2CACHE_CIALL : THCacheInst_void<0b10111, "th.l2cache.ciall">;
751}
752
753let Predicates = [HasVendorXTHeadSync], DecoderNamespace = "THeadSync" in {
754def TH_SFENCE_VMAS : THCacheInst_rr<0b0000010, "th.sfence.vmas">;
755def TH_SYNC        : THCacheInst_void<0b11000, "th.sync">;
756def TH_SYNC_S      : THCacheInst_void<0b11001, "th.sync.s">;
757def TH_SYNC_I      : THCacheInst_void<0b11010, "th.sync.i">;
758def TH_SYNC_IS     : THCacheInst_void<0b11011, "th.sync.is">;
759}
760
761def AddrRegRegScale : ComplexPattern<iPTR, 3, "SelectAddrRegRegScale<3>">;
762def AddrRegZextRegScale
763    : ComplexPattern<i64, 3, "SelectAddrRegZextRegScale<3, 32>",
764                     [], [], 10>;
765
766multiclass LdIdxPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT> {
767def : Pat<(vt (LoadOp (AddrRegRegScale (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2))),
768          (Inst GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
769}
770
771multiclass LdZextIdxPat<PatFrag LoadOp, RVInst Inst, ValueType vt = i64> {
772def : Pat<(vt (LoadOp (AddrRegZextRegScale (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2))),
773          (Inst GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
774}
775
776multiclass StIdxPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
777                    ValueType vt = XLenVT> {
778def : Pat<(StoreOp (vt StTy:$rd),
779            (AddrRegRegScale (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2)),
780          (Inst StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
781}
782
783multiclass StZextIdxPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
784                        ValueType vt = i64> {
785def : Pat<(StoreOp (vt StTy:$rd),
786            (AddrRegZextRegScale (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2)),
787          (Inst StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
788}
789
790let Predicates = [HasVendorXTHeadMemIdx] in {
791defm : LdIdxPat<extloadi8, TH_LRB>;
792defm : LdIdxPat<sextloadi8, TH_LRB>;
793defm : LdIdxPat<zextloadi8, TH_LRBU>;
794
795defm : LdIdxPat<extloadi16, TH_LRH>;
796defm : LdIdxPat<sextloadi16, TH_LRH>;
797defm : LdIdxPat<zextloadi16, TH_LRHU>;
798
799defm : StIdxPat<truncstorei8, TH_SRB, GPR>;
800defm : StIdxPat<truncstorei16, TH_SRH, GPR>;
801}
802
803let Predicates = [HasVendorXTHeadMemIdx, IsRV32] in {
804defm : LdIdxPat<load, TH_LRW, i32>;
805defm : StIdxPat<store, TH_SRW, GPR, i32>;
806}
807
808let Predicates = [HasVendorXTHeadMemIdx, IsRV64] in {
809defm : LdZextIdxPat<extloadi8, TH_LURB>;
810defm : LdZextIdxPat<sextloadi8, TH_LURB>;
811defm : LdZextIdxPat<zextloadi8, TH_LURBU>;
812
813defm : LdZextIdxPat<extloadi16, TH_LURH>;
814defm : LdZextIdxPat<sextloadi16, TH_LURH>;
815defm : LdZextIdxPat<zextloadi16, TH_LURHU>;
816
817defm : LdIdxPat<extloadi32, TH_LRW, i64>;
818defm : LdIdxPat<sextloadi32, TH_LRW, i64>;
819defm : LdIdxPat<zextloadi32, TH_LRWU, i64>;
820
821defm : LdZextIdxPat<extloadi32, TH_LURW>;
822defm : LdZextIdxPat<sextloadi32, TH_LURW>;
823defm : LdZextIdxPat<zextloadi32, TH_LURWU>;
824
825defm : LdIdxPat<load, TH_LRD, i64>;
826defm : LdZextIdxPat<load, TH_LURD>;
827
828defm : StZextIdxPat<truncstorei8, TH_SURB, GPR>;
829defm : StZextIdxPat<truncstorei16, TH_SURH, GPR>;
830defm : StIdxPat<truncstorei32, TH_SRW, GPR, i64>;
831defm : StZextIdxPat<truncstorei32, TH_SURW, GPR, i64>;
832defm : StIdxPat<store, TH_SRD, GPR, i64>;
833defm : StZextIdxPat<store, TH_SURD, GPR>;
834}
835
836let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF] in {
837defm : LdIdxPat<load, TH_FLRW, f32>;
838defm : StIdxPat<store, TH_FSRW, FPR32, f32>;
839}
840
841let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD] in {
842defm : LdIdxPat<load, TH_FLRD, f64>;
843defm : StIdxPat<store, TH_FSRD, FPR64, f64>;
844}
845
846let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV64] in {
847defm : LdZextIdxPat<load, TH_FLURW, f32>;
848defm : StZextIdxPat<store, TH_FSURW, FPR32, f32>;
849}
850
851let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV64] in {
852defm : LdZextIdxPat<load, TH_FLURD, f64>;
853defm : StZextIdxPat<store, TH_FSURD, FPR64, f64>;
854}
855
856def simm5shl2 : ComplexPattern<XLenVT, 2, "selectSimm5Shl2">;
857
858multiclass StoreUpdatePat<PatFrag st, Instruction Inst, ValueType vt = XLenVT> {
859def : Pat<(st (vt GPR:$rd), GPR:$rs1, (simm5shl2 simm5:$simm5, uimm2:$uimm2)),
860          (Inst GPR:$rd, GPR:$rs1, simm5:$simm5, uimm2:$uimm2)>;
861}
862
863let Predicates = [HasVendorXTHeadMemIdx] in {
864defm : StoreUpdatePat<post_truncsti8, TH_SBIA>;
865defm : StoreUpdatePat<pre_truncsti8, TH_SBIB>;
866defm : StoreUpdatePat<post_truncsti16, TH_SHIA>;
867defm : StoreUpdatePat<pre_truncsti16, TH_SHIB>;
868}
869
870let Predicates = [HasVendorXTHeadMemIdx, IsRV32] in {
871defm : StoreUpdatePat<post_store, TH_SWIA, i32>;
872defm : StoreUpdatePat<pre_store, TH_SWIB, i32>;
873}
874
875let Predicates = [HasVendorXTHeadMemIdx, IsRV64] in {
876defm : StoreUpdatePat<post_truncsti32, TH_SWIA, i64>;
877defm : StoreUpdatePat<pre_truncsti32, TH_SWIB, i64>;
878defm : StoreUpdatePat<post_store, TH_SDIA, i64>;
879defm : StoreUpdatePat<pre_store, TH_SDIB, i64>;
880}
881