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