[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVInstrInfoXTHead.td
blob1d44b1ad26364e0b557740841d701c59a31589ef
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.
11 //===----------------------------------------------------------------------===//
13 //===----------------------------------------------------------------------===//
14 // T-HEAD specific DAG Nodes.
15 //===----------------------------------------------------------------------===//
17 def SDT_LoadPair : SDTypeProfile<2, 2, [SDTCisSameAs<0, 1>,
18                                         SDTCisSameAs<1, 3>,
19                                         SDTCisPtrTy<2>,
20                                         SDTCisVT<3, XLenVT>]>;
21 def SDT_StorePair : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,
22                                          SDTCisSameAs<1, 3>,
23                                          SDTCisPtrTy<2>,
24                                          SDTCisVT<3, XLenVT>]>;
26 def th_lwud : SDNode<"RISCVISD::TH_LWUD", SDT_LoadPair,
27                      [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
28 def th_lwd : SDNode<"RISCVISD::TH_LWD", SDT_LoadPair,
29                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
30 def th_ldd : SDNode<"RISCVISD::TH_LDD", SDT_LoadPair,
31                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
32 def th_swd : SDNode<"RISCVISD::TH_SWD", SDT_StorePair,
33                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
34 def th_sdd : SDNode<"RISCVISD::TH_SDD", SDT_StorePair,
35                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
37 //===----------------------------------------------------------------------===//
38 // Instruction class templates
39 //===----------------------------------------------------------------------===//
41 class 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";
49 class 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";
57 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
58 // op vd, vs1, vs2, vm (reverse the order of vs1 and vs2)
59 class 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");
68 // op vd, rs1, vs2, vm (reverse the order of rs1 and vs2)
69 class 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");
77 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
79 let Predicates = [HasVendorXTHeadBa], DecoderNamespace = "XTHeadBa",
80     hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
81 class 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;
90 let Predicates = [HasVendorXTHeadBb], DecoderNamespace = "XTHeadBb",
91     hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
92 class 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">;
97 class 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;
107 class 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">;
112 let Predicates = [HasVendorXTHeadBb, IsRV64], DecoderNamespace = "XTHeadBb",
113     hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
114 class 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">;
119 let Predicates = [HasVendorXTHeadCondMov], DecoderNamespace = "XTHeadCondMov",
120     hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in
121 class 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";
128 let Predicates = [HasVendorXTHeadMac], DecoderNamespace = "XTHeadMac",
129     hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in
130 class 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";
137 let Predicates = [HasVendorXTHeadMemPair], DecoderNamespace = "XTHeadMemPair",
138     hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
139 class 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";
151 let Predicates = [HasVendorXTHeadMemPair], DecoderNamespace = "XTHeadMemPair",
152     hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
153 class 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";
163 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
164 class 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;
171 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
172 class 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;
178 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
179 class 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;
186 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
187 class 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;
196 class 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";
209 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
210 class 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;
219 class 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";
232 //===----------------------------------------------------------------------===//
233 // Combination of instruction classes.
234 // Use these multiclasses to define instructions more easily.
235 //===----------------------------------------------------------------------===//
237 multiclass THVdotVMAQA_VX<string opcodestr, bits<6> funct6> {
238   let RVVConstraint = WidenV in
239   def _VX : THVdotALUrVX<funct6, OPMVX, opcodestr # ".vx", EarlyClobber=1>;
242 multiclass 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>;
248 //===----------------------------------------------------------------------===//
249 // Instructions
250 //===----------------------------------------------------------------------===//
252 let Predicates = [HasVendorXTHeadBa] in
253 def TH_ADDSL : THShiftALU_rri<0b001, "th.addsl">,
254                Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
256 let Predicates = [HasVendorXTHeadBb] in {
257 def TH_SRRI : THShift_ri<0b00010, 0b001, "th.srri">;
258 def TH_EXT : THBitfieldExtract_rii<0b010, "th.ext">;
259 def TH_EXTU : THBitfieldExtract_rii<0b011, "th.extu">;
260 def TH_FF0 : THRev_r<0b10000, 0b10, "th.ff0">;
261 def TH_FF1 : THRev_r<0b10000, 0b11, "th.ff1">;
262 def TH_REV : THRev_r<0b10000, 0b01, "th.rev">;
263 def TH_TSTNBZ : THRev_r<0b10000, 0b00, "th.tstnbz">;
264 } // Predicates = [HasVendorXTHeadBb]
266 let Predicates = [HasVendorXTHeadBb, IsRV64], IsSignExtendingOpW = 1 in {
267 def TH_SRRIW : THShiftW_ri<0b0001010, 0b001, "th.srriw">;
268 def TH_REVW : THRev_r<0b10010, 0b00, "th.revw">;
269 } // Predicates = [HasVendorXTHeadBb, IsRV64]
271 let Predicates = [HasVendorXTHeadBs], DecoderNamespace = "XTHeadBs",
272     IsSignExtendingOpW = 1 in
273 def TH_TST : RVBShift_ri<0b10001, 0b001, OPC_CUSTOM_0, "th.tst">,
274              Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
276 let Predicates = [HasVendorXTHeadCondMov] in {
277 def TH_MVEQZ : THCondMov_rr<0b0100000, "th.mveqz">;
278 def TH_MVNEZ : THCondMov_rr<0b0100001, "th.mvnez">;
279 } // Predicates = [HasVendorXTHeadCondMov]
281 let Predicates = [HasVendorXTHeadMac] in {
282 def TH_MULA : THMulAccumulate_rr<0b0010000, "th.mula">;
283 def TH_MULS : THMulAccumulate_rr<0b0010001, "th.muls">;
284 }  // Predicates = [HasVendorXTHeadMac]
286 let Predicates = [HasVendorXTHeadMac], IsSignExtendingOpW = 1 in {
287 def TH_MULAH : THMulAccumulate_rr<0b0010100, "th.mulah">;
288 def TH_MULSH : THMulAccumulate_rr<0b0010101, "th.mulsh">;
289 } // Predicates = [HasVendorXTHeadMac], IsSignExtendingOpW = 1
291 let Predicates = [HasVendorXTHeadMac, IsRV64], IsSignExtendingOpW = 1 in {
292 def TH_MULAW : THMulAccumulate_rr<0b0010010, "th.mulaw">;
293 def TH_MULSW : THMulAccumulate_rr<0b0010011, "th.mulsw">;
294 } // Predicates = [HasVendorXTHeadMac, IsRV64]
296 let Predicates = [HasVendorXTHeadMemPair] in {
297 def TH_LWUD : THLoadPair<0b11110, "th.lwud">,
298               Sched<[WriteLDW, WriteLDW, ReadMemBase]>;
299 def TH_SWD  : THStorePair<0b11100, "th.swd">,
300               Sched<[WriteSTW, WriteSTW, ReadStoreData, ReadMemBase]>;
301 let IsSignExtendingOpW = 1 in
302 def TH_LWD  : THLoadPair<0b11100, "th.lwd">,
303               Sched<[WriteLDW, WriteLDW, ReadMemBase]>;
306 let Predicates = [HasVendorXTHeadMemPair, IsRV64] in {
307 def TH_LDD : THLoadPair<0b11111, "th.ldd">,
308              Sched<[WriteLDD, WriteLDD, ReadMemBase]>;
309 def TH_SDD : THStorePair<0b11111, "th.sdd">,
310              Sched<[WriteSTD, WriteSTD, ReadStoreData, ReadMemBase]>;
313 let Predicates = [HasVendorXTHeadMemIdx], DecoderNamespace = "XTHeadMemIdx" in {
314 // T-Head Load/Store + Update instructions.
315 def TH_LBIA : THLoadUpdate<0b00011, "th.lbia">,
316               Sched<[WriteLDB, ReadMemBase]>;
317 def TH_LBIB : THLoadUpdate<0b00001, "th.lbib">,
318               Sched<[WriteLDB, ReadMemBase]>;
319 def TH_LBUIA : THLoadUpdate<0b10011, "th.lbuia">,
320                Sched<[WriteLDB, ReadMemBase]>;
321 def TH_LBUIB : THLoadUpdate<0b10001, "th.lbuib">,
322                Sched<[WriteLDB, ReadMemBase]>;
324 def TH_LHIA : THLoadUpdate<0b00111, "th.lhia">,
325               Sched<[WriteLDH, ReadMemBase]>;
326 def TH_LHIB : THLoadUpdate<0b00101, "th.lhib">,
327               Sched<[WriteLDH, ReadMemBase]>;
328 def TH_LHUIA : THLoadUpdate<0b10111, "th.lhuia">,
329                Sched<[WriteLDH, ReadMemBase]>;
330 def TH_LHUIB : THLoadUpdate<0b10101, "th.lhuib">,
331                Sched<[WriteLDH, ReadMemBase]>;
333 def TH_LWIA : THLoadUpdate<0b01011, "th.lwia">,
334               Sched<[WriteLDW, ReadMemBase]>;
335 def TH_LWIB : THLoadUpdate<0b01001, "th.lwib">,
336               Sched<[WriteLDW, ReadMemBase]>;
338 def TH_SBIA : THStoreUpdate<0b00011, "th.sbia">,
339               Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
340 def TH_SBIB : THStoreUpdate<0b00001, "th.sbib">,
341               Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
343 def TH_SHIA : THStoreUpdate<0b00111, "th.shia">,
344               Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
345 def TH_SHIB : THStoreUpdate<0b00101, "th.shib">,
346               Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
348 def TH_SWIA : THStoreUpdate<0b01011, "th.swia">,
349               Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
350 def TH_SWIB : THStoreUpdate<0b01001, "th.swib">,
351               Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
353 // T-Head Load/Store Indexed instructions.
354 def TH_LRB : THLoadIndexed<GPR, 0b00000, "th.lrb">,
355              Sched<[WriteLDB, ReadMemBase]>;
356 def TH_LRBU : THLoadIndexed<GPR, 0b10000, "th.lrbu">,
357               Sched<[WriteLDB, ReadMemBase]>;
358 def TH_LURB : THLoadIndexed<GPR, 0b00010, "th.lurb">,
359               Sched<[WriteLDB, ReadMemBase]>;
360 def TH_LURBU : THLoadIndexed<GPR, 0b10010, "th.lurbu">,
361                Sched<[WriteLDB, ReadMemBase]>;
363 def TH_LRH : THLoadIndexed<GPR, 0b00100, "th.lrh">,
364              Sched<[WriteLDH, ReadMemBase]>;
365 def TH_LRHU : THLoadIndexed<GPR, 0b10100, "th.lrhu">,
366               Sched<[WriteLDH, ReadMemBase]>;
367 def TH_LURH : THLoadIndexed<GPR, 0b00110, "th.lurh">,
368               Sched<[WriteLDB, ReadMemBase]>;
369 def TH_LURHU : THLoadIndexed<GPR, 0b10110, "th.lurhu">,
370                Sched<[WriteLDB, ReadMemBase]>;
372 def TH_LRW : THLoadIndexed<GPR, 0b01000, "th.lrw">,
373              Sched<[WriteLDW, ReadMemBase]>;
374 def TH_LURW : THLoadIndexed<GPR, 0b01010, "th.lurw">,
375               Sched<[WriteLDB, ReadMemBase]>;
377 def TH_SRB : THStoreIndexed<GPR, 0b00000, "th.srb">,
378              Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
379 def TH_SURB : THStoreIndexed<GPR, 0b00010, "th.surb">,
380               Sched<[WriteLDB, ReadMemBase]>;
382 def TH_SRH : THStoreIndexed<GPR, 0b00100, "th.srh">,
383              Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
384 def TH_SURH : THStoreIndexed<GPR, 0b00110, "th.surh">,
385               Sched<[WriteLDB, ReadMemBase]>;
387 def TH_SRW : THStoreIndexed<GPR, 0b01000, "th.srw">,
388              Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
389 def TH_SURW : THStoreIndexed<GPR, 0b01010, "th.surw">,
390               Sched<[WriteLDB, ReadMemBase]>;
393 let Predicates = [HasVendorXTHeadMemIdx, IsRV64], DecoderNamespace = "XTHeadMemIdx" in {
394 // T-Head Load/Store + Update instructions.
395 def TH_LWUIA : THLoadUpdate<0b11011, "th.lwuia">,
396                Sched<[WriteLDH, ReadMemBase]>;
397 def TH_LWUIB : THLoadUpdate<0b11001, "th.lwuib">,
398                Sched<[WriteLDH, ReadMemBase]>;
400 def TH_LDIA : THLoadUpdate<0b01111, "th.ldia">,
401               Sched<[WriteLDW, ReadMemBase]>;
402 def TH_LDIB : THLoadUpdate<0b01101, "th.ldib">,
403               Sched<[WriteLDW, ReadMemBase]>;
405 def TH_SDIA : THStoreUpdate<0b01111, "th.sdia">,
406               Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
407 def TH_SDIB : THStoreUpdate<0b01101, "th.sdib">,
408               Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
410 // T-Head Load/Store Indexed instructions.
411 def TH_LRWU : THLoadIndexed<GPR, 0b11000, "th.lrwu">,
412               Sched<[WriteLDW, ReadMemBase]>;
413 def TH_LURWU : THLoadIndexed<GPR, 0b11010, "th.lurwu">,
414                Sched<[WriteLDB, ReadMemBase]>;
416 def TH_LRD : THLoadIndexed<GPR, 0b01100, "th.lrd">,
417              Sched<[WriteLDW, ReadMemBase]>;
418 def TH_LURD : THLoadIndexed<GPR, 0b01110, "th.lurd">,
419               Sched<[WriteLDB, ReadMemBase]>;
421 def TH_SRD : THStoreIndexed<GPR, 0b01100, "th.srd">,
422              Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
423 def TH_SURD : THStoreIndexed<GPR, 0b01110, "th.surd">,
424               Sched<[WriteLDB, ReadMemBase]>;
427 // T-Head Load/Store Indexed instructions for floating point registers.
429 let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF],
430     DecoderNamespace = "XTHeadFMemIdx" in {
431 def TH_FLRW : THLoadIndexed<FPR32, 0b01000, "th.flrw">,
432               Sched<[WriteFLD32, ReadFMemBase]>;
433 def TH_FSRW : THStoreIndexed<FPR32, 0b01000, "th.fsrw">,
434               Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]>;
437 let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD],
438     DecoderNamespace = "XTHeadFMemIdx" in {
439 def TH_FLRD : THLoadIndexed<FPR64, 0b01100, "th.flrd">,
440               Sched<[WriteFLD64, ReadFMemBase]>;
441 def TH_FSRD : THStoreIndexed<FPR64, 0b01100, "th.fsrd">,
442               Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]>;
445 let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV64],
446     DecoderNamespace = "XTHeadFMemIdx" in {
447 def TH_FLURW : THLoadIndexed<FPR32, 0b01010, "th.flurw">,
448                Sched<[WriteFLD32, ReadFMemBase]>;
449 def TH_FSURW : THStoreIndexed<FPR32, 0b01010, "th.fsurw">,
450                Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]>;
453 let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV64],
454     DecoderNamespace = "XTHeadFMemIdx" in {
455 def TH_FLURD : THLoadIndexed<FPR64, 0b01110, "th.flurd">,
456                Sched<[WriteFLD64, ReadFMemBase]>;
457 def TH_FSURD : THStoreIndexed<FPR64, 0b01110, "th.fsurd">,
458                Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]>;
461 let Predicates = [HasVendorXTHeadVdot] in {
462 defm THVdotVMAQA      : THVdotVMAQA<"th.vmaqa",     0b100000>;
463 defm THVdotVMAQAU     : THVdotVMAQA<"th.vmaqau",    0b100010>;
464 defm THVdotVMAQASU    : THVdotVMAQA<"th.vmaqasu",   0b100100>;
465 defm THVdotVMAQAUS    : THVdotVMAQA_VX<"th.vmaqaus",0b100110>;
468 // Associate LMUL with tablegen records of register classes.
469 def THVdotV_M1  : LMULInfo<0b000,  8,   VR, VR,   VR,   VR,   VR, "M1">;
470 def THVdotV_M2  : LMULInfo<0b001, 16, VRM2, VRM2, VR,   VR,   VR, "M2">;
471 def THVdotV_M4  : LMULInfo<0b010, 32, VRM4, VRM4, VRM2, VR,   VR, "M4">;
472 def THVdotV_M8  : LMULInfo<0b011, 64, VRM8, VRM8, VRM4, VRM2, VR, "M8">;
474 defvar MxListTHVdot = [V_MF2, THVdotV_M1, THVdotV_M2, THVdotV_M4, THVdotV_M8];
476 defset 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>;
484 //===----------------------------------------------------------------------===//
485 // Combination of instruction classes.
486 // Use these multiclasses to define instructions more easily.
487 //===----------------------------------------------------------------------===//
489 multiclass VPseudoVMAQA_VV_VX {
490   foreach m = MxListTHVdot in {
491     // TODO: Add Sched
492     defm "" : VPseudoTernaryW_VV<m>;
493     defm "" : VPseudoTernaryW_VX<m>;
494   }
497 multiclass VPseudoVMAQA_VX {
498   foreach m = MxListTHVdot in {
499     // TODO: Add Sched
500     defm "" : VPseudoTernaryW_VX<m>;
501   }
504 multiclass 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   }
516 multiclass 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   }
529 multiclass VPatTernaryVMAQA_VV_VX<string intrinsic, string instruction,
530                                   list<VTypeInfoToWide> vtilist>
531     : VPatTernaryVMAQA_VV<intrinsic, instruction, vtilist>,
532       VPatTernaryVMAQA_VX<intrinsic, instruction, vtilist>;
534 //===----------------------------------------------------------------------===//
535 // Pseudo-instructions and codegen patterns
536 //===----------------------------------------------------------------------===//
538 let Predicates = [HasVendorXTHeadBa] in {
539 def : Pat<(add (XLenVT GPR:$rs1), (shl GPR:$rs2, uimm2:$uimm2)),
540           (TH_ADDSL GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
542 // Reuse complex patterns from StdExtZba
543 def : Pat<(add_non_imm12 sh1add_op:$rs1, (XLenVT GPR:$rs2)),
544           (TH_ADDSL GPR:$rs2, sh1add_op:$rs1, 1)>;
545 def : Pat<(add_non_imm12 sh2add_op:$rs1, (XLenVT GPR:$rs2)),
546           (TH_ADDSL GPR:$rs2, sh2add_op:$rs1, 2)>;
547 def : Pat<(add_non_imm12 sh3add_op:$rs1, (XLenVT GPR:$rs2)),
548           (TH_ADDSL GPR:$rs2, sh3add_op:$rs1, 3)>;
550 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 6)), GPR:$rs2),
551           (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 1), 1)>;
552 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 10)), GPR:$rs2),
553           (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 2), 1)>;
554 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 18)), GPR:$rs2),
555           (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 3), 1)>;
556 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 12)), GPR:$rs2),
557           (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 1), 2)>;
558 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 20)), GPR:$rs2),
559           (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 2), 2)>;
560 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 36)), GPR:$rs2),
561           (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 3), 2)>;
562 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 24)), GPR:$rs2),
563           (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 1), 3)>;
564 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 40)), GPR:$rs2),
565           (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 2), 3)>;
566 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 72)), GPR:$rs2),
567           (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 3), 3)>;
569 def : Pat<(add (XLenVT GPR:$r), CSImm12MulBy4:$i),
570           (TH_ADDSL GPR:$r, (ADDI (XLenVT X0), (SimmShiftRightBy2XForm CSImm12MulBy4:$i)), 2)>;
571 def : Pat<(add (XLenVT GPR:$r), CSImm12MulBy8:$i),
572           (TH_ADDSL GPR:$r, (ADDI (XLenVT X0), (SimmShiftRightBy3XForm CSImm12MulBy8:$i)), 3)>;
574 def : Pat<(mul (XLenVT GPR:$r), C3LeftShift:$i),
575           (SLLI (TH_ADDSL GPR:$r, GPR:$r, 1),
576                 (TrailingZeros C3LeftShift:$i))>;
577 def : Pat<(mul (XLenVT GPR:$r), C5LeftShift:$i),
578           (SLLI (TH_ADDSL GPR:$r, GPR:$r, 2),
579                 (TrailingZeros C5LeftShift:$i))>;
580 def : Pat<(mul (XLenVT GPR:$r), C9LeftShift:$i),
581           (SLLI (TH_ADDSL GPR:$r, GPR:$r, 3),
582                 (TrailingZeros C9LeftShift:$i))>;
584 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 11)),
585           (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 2), 1)>;
586 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 19)),
587           (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 3), 1)>;
588 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 13)),
589           (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 1), 2)>;
590 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 21)),
591           (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 2), 2)>;
592 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 37)),
593           (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 3), 2)>;
594 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 25)),
595           (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 2), (TH_ADDSL GPR:$r, GPR:$r, 2), 2)>;
596 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 41)),
597           (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 2), 3)>;
598 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 73)),
599           (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 3), 3)>;
600 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 27)),
601           (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 3), (TH_ADDSL GPR:$r, GPR:$r, 3), 1)>;
602 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 45)),
603           (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 3), (TH_ADDSL GPR:$r, GPR:$r, 3), 2)>;
604 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 81)),
605           (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 3), (TH_ADDSL GPR:$r, GPR:$r, 3), 3)>;
607 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 200)),
608           (SLLI (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 2),
609                           (TH_ADDSL GPR:$r, GPR:$r, 2), 2), 3)>;
610 } // Predicates = [HasVendorXTHeadBa]
612 let Predicates = [HasVendorXTHeadBb] in {
613 def : PatGprImm<rotr, TH_SRRI, uimmlog2xlen>;
614 // There's no encoding for a rotate-left-immediate in X-THead-Bb, as
615 // it can be implemented with th.srri by negating the immediate.
616 def : Pat<(rotl (XLenVT GPR:$rs1), uimmlog2xlen:$shamt),
617           (TH_SRRI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
618 def : Pat<(sext_inreg (XLenVT GPR:$rs1), i32), (TH_EXT GPR:$rs1, 31, 0)>;
619 def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (TH_EXT GPR:$rs1, 15, 0)>;
620 def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (TH_EXT GPR:$rs1, 7, 0)>;
621 def : Pat<(sext_inreg (XLenVT GPR:$rs1), i1), (TH_EXT GPR:$rs1, 0, 0)>;
622 def : PatGpr<ctlz, TH_FF1>;
623 def : Pat<(XLenVT (ctlz (xor (XLenVT GPR:$rs1), -1))), (TH_FF0 GPR:$rs1)>;
624 def : PatGpr<bswap, TH_REV>;
625 } // Predicates = [HasVendorXTHeadBb]
627 let Predicates = [HasVendorXTHeadBb, IsRV64] in {
628 def : PatGprImm<riscv_rorw, TH_SRRIW, uimm5>;
629 def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
630           (TH_SRRIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
631 def : Pat<(sra (bswap i64:$rs1), (i64 32)),
632           (TH_REVW i64:$rs1)>;
633 def : Pat<(binop_allwusers<srl> (bswap i64:$rs1), (i64 32)),
634           (TH_REVW i64:$rs1)>;
635 def : Pat<(riscv_clzw i64:$rs1),
636           (TH_FF0 (SLLI (XORI i64:$rs1, -1), 32))>;
637 } // Predicates = [HasVendorXTHeadBb, IsRV64]
639 let Predicates = [HasVendorXTHeadBs] in {
640 def : Pat<(and (srl (XLenVT GPR:$rs1), uimmlog2xlen:$shamt), 1),
641           (TH_TST GPR:$rs1, uimmlog2xlen:$shamt)>;
642 def : Pat<(XLenVT (seteq (and (XLenVT GPR:$rs1), SingleBitSetMask:$mask), 0)),
643           (TH_TST (XORI GPR:$rs1, -1), SingleBitSetMask:$mask)>;
644 } // Predicates = [HasVendorXTHeadBs]
646 let Predicates = [HasVendorXTHeadCondMov] in {
647 def : Pat<(select (XLenVT GPR:$cond), (XLenVT GPR:$a), (XLenVT GPR:$b)),
648           (TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>;
649 def : Pat<(select (XLenVT GPR:$cond), (XLenVT GPR:$a), (XLenVT 0)),
650           (TH_MVEQZ GPR:$a, (XLenVT X0), GPR:$cond)>;
651 def : Pat<(select (XLenVT GPR:$cond), (XLenVT 0), (XLenVT GPR:$b)),
652           (TH_MVNEZ GPR:$b, (XLenVT X0), GPR:$cond)>;
654 def : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT GPR:$b)),
655           (TH_MVNEZ GPR:$a, GPR:$b, GPR:$cond)>;
656 def : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT GPR:$b)),
657           (TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>;
658 def : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT 0)),
659           (TH_MVNEZ GPR:$a, (XLenVT X0), GPR:$cond)>;
660 def : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT 0)),
661           (TH_MVEQZ GPR:$a, (XLenVT X0), GPR:$cond)>;
662 def : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT 0), (XLenVT GPR:$b)),
663           (TH_MVEQZ GPR:$b, (XLenVT X0), GPR:$cond)>;
664 def : Pat<(select (riscv_setne (XLenVT GPR:$cond)),  (XLenVT 0), (XLenVT GPR:$b)),
665           (TH_MVNEZ GPR:$b, (XLenVT X0), GPR:$cond)>;
666 } // Predicates = [HasVendorXTHeadCondMov]
668 let Predicates = [HasVendorXTHeadMac] in {
669 def : Pat<(add GPR:$rd, (mul (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))),
670           (TH_MULA GPR:$rd, GPR:$rs1, GPR:$rs2)>;
671 def : Pat<(sub GPR:$rd, (mul (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))),
672           (TH_MULS GPR:$rd, GPR:$rs1, GPR:$rs2)>;
673 } // Predicates = [HasVendorXTHeadMac]
675 let Predicates = [HasVendorXTHeadMac, IsRV64] in {
676 // mulaw, mulsw are available only in RV64.
677 def : Pat<(binop_allwusers<add> GPR:$rd, (mul GPR:$rs1, GPR:$rs2)),
678           (TH_MULAW GPR:$rd, GPR:$rs1, GPR:$rs2)>;
679 def : Pat<(binop_allwusers<sub> GPR:$rd, (mul GPR:$rs1, GPR:$rs2)),
680           (TH_MULSW GPR:$rd, GPR:$rs1, GPR:$rs2)>;
681 // mulah, mulsh produce a sign-extended result.
682 def : Pat<(binop_allwusers<add> GPR:$rd, (mul
683             (sexti16 (i64 GPR:$rs1)),
684             (sexti16 (i64 GPR:$rs2)))),
685           (TH_MULAH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
686 def : Pat<(binop_allwusers<sub> GPR:$rd, (mul
687             (sexti16 (i64 GPR:$rs1)),
688             (sexti16 (i64 GPR:$rs2)))),
689           (TH_MULSH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
690 } // Predicates = [HasVendorXTHeadMac, IsRV64]
692 let Predicates = [HasVendorXTHeadMac, IsRV32] in {
693 def : Pat<(i32 (add GPR:$rd, (mul (sexti16 (i32 GPR:$rs1)),
694                                   (sexti16 (i32 GPR:$rs2))))),
695           (TH_MULAH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
696 def : Pat<(i32 (sub GPR:$rd, (mul (sexti16 (i32 GPR:$rs1)),
697                                   (sexti16 (i32 GPR:$rs2))))),
698           (TH_MULSH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
699 } // Predicates = [HasVendorXTHeadMac, IsRV32]
701 defm PseudoTHVdotVMAQA      : VPseudoVMAQA_VV_VX;
702 defm PseudoTHVdotVMAQAU     : VPseudoVMAQA_VV_VX;
703 defm PseudoTHVdotVMAQASU    : VPseudoVMAQA_VV_VX;
704 defm PseudoTHVdotVMAQAUS    : VPseudoVMAQA_VX;
706 let Predicates = [HasVendorXTHeadVdot] in {
707 defm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqa",  "PseudoTHVdotVMAQA",
708                               AllQuadWidenableInt8NoVLMulVectors>;
709 defm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqau", "PseudoTHVdotVMAQAU",
710                               AllQuadWidenableInt8NoVLMulVectors>;
711 defm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqasu","PseudoTHVdotVMAQASU",
712                               AllQuadWidenableInt8NoVLMulVectors>;
713 defm : VPatTernaryVMAQA_VX<"int_riscv_th_vmaqaus",   "PseudoTHVdotVMAQAUS",
714                            AllQuadWidenableInt8NoVLMulVectors>;
717 def uimm2_3_XFORM : SDNodeXForm<imm, [{
718   return CurDAG->getTargetConstant((N->getZExtValue() >> 3) & 0x3,
719                                    SDLoc(N), Subtarget->getXLenVT());
720 }]>;
722 def uimm2_3 : Operand<XLenVT>, ImmLeaf<XLenVT, [{
723   return isShiftedUInt<2, 3>(Imm);
724 }], uimm2_3_XFORM>;
726 def uimm2_4_XFORM : SDNodeXForm<imm, [{
727   return CurDAG->getTargetConstant((N->getZExtValue() >> 4) & 0x3,
728                                    SDLoc(N), Subtarget->getXLenVT());
729 }]>;
731 def uimm2_4 : Operand<XLenVT>, ImmLeaf<XLenVT, [{
732   return isShiftedUInt<2, 4>(Imm);
733 }], uimm2_4_XFORM>;
735 let Predicates = [HasVendorXTHeadMemPair, IsRV64] in {
736 def : Pat<(th_lwud i64:$rs1, uimm2_3:$uimm2_3), (TH_LWUD i64:$rs1, uimm2_3:$uimm2_3, 3)>;
737 def : Pat<(th_ldd i64:$rs1, uimm2_4:$uimm2_4), (TH_LDD i64:$rs1, uimm2_4:$uimm2_4, 4)>;
739 def : Pat<(th_sdd i64:$rd1, i64:$rd2, i64:$rs1, uimm2_4:$uimm2_4),
740           (TH_SDD i64:$rd1, i64:$rd2, i64:$rs1, uimm2_4:$uimm2_4, 4)>;
743 let Predicates = [HasVendorXTHeadMemPair] in {
744   def : Pat<(th_lwd GPR:$rs1, uimm2_3:$uimm2_3), (TH_LWD GPR:$rs1, uimm2_3:$uimm2_3, 3)>;
745   def : Pat<(th_swd GPR:$rd1, GPR:$rd2, GPR:$rs1, uimm2_3:$uimm2_3),
746             (TH_SWD GPR:$rd1, GPR:$rd2, GPR:$rs1, uimm2_3:$uimm2_3, 3)>;
749 let Predicates = [HasVendorXTHeadCmo], DecoderNamespace = "XTHeadCmo" in {
750 def TH_DCACHE_CSW    : THCacheInst_r<0b00001, "th.dcache.csw">;
751 def TH_DCACHE_ISW    : THCacheInst_r<0b00010, "th.dcache.isw">;
752 def TH_DCACHE_CISW   : THCacheInst_r<0b00011, "th.dcache.cisw">;
753 def TH_DCACHE_CVAL1  : THCacheInst_r<0b00100, "th.dcache.cval1">;
754 def TH_DCACHE_CVA    : THCacheInst_r<0b00101, "th.dcache.cva">;
755 def TH_DCACHE_IVA    : THCacheInst_r<0b00110, "th.dcache.iva">;
756 def TH_DCACHE_CIVA   : THCacheInst_r<0b00111, "th.dcache.civa">;
757 def TH_DCACHE_CPAL1  : THCacheInst_r<0b01000, "th.dcache.cpal1">;
758 def TH_DCACHE_CPA    : THCacheInst_r<0b01001, "th.dcache.cpa">;
759 def TH_DCACHE_IPA    : THCacheInst_r<0b01010, "th.dcache.ipa">;
760 def TH_DCACHE_CIPA   : THCacheInst_r<0b01011, "th.dcache.cipa">;
761 def TH_ICACHE_IVA    : THCacheInst_r<0b10000, "th.icache.iva">;
762 def TH_ICACHE_IPA    : THCacheInst_r<0b11000, "th.icache.ipa">;
764 def TH_DCACHE_CALL   : THCacheInst_void<0b00001, "th.dcache.call">;
765 def TH_DCACHE_IALL   : THCacheInst_void<0b00010, "th.dcache.iall">;
766 def TH_DCACHE_CIALL  : THCacheInst_void<0b00011, "th.dcache.ciall">;
767 def TH_ICACHE_IALL   : THCacheInst_void<0b10000, "th.icache.iall">;
768 def TH_ICACHE_IALLS  : THCacheInst_void<0b10001, "th.icache.ialls">;
769 def TH_L2CACHE_CALL  : THCacheInst_void<0b10101, "th.l2cache.call">;
770 def TH_L2CACHE_IALL  : THCacheInst_void<0b10110, "th.l2cache.iall">;
771 def TH_L2CACHE_CIALL : THCacheInst_void<0b10111, "th.l2cache.ciall">;
774 let Predicates = [HasVendorXTHeadSync], DecoderNamespace = "XTHeadSync" in {
775 def TH_SFENCE_VMAS : THCacheInst_rr<0b0000010, "th.sfence.vmas">;
776 def TH_SYNC        : THCacheInst_void<0b11000, "th.sync">;
777 def TH_SYNC_S      : THCacheInst_void<0b11001, "th.sync.s">;
778 def TH_SYNC_I      : THCacheInst_void<0b11010, "th.sync.i">;
779 def TH_SYNC_IS     : THCacheInst_void<0b11011, "th.sync.is">;
782 def AddrRegRegScale : ComplexPattern<iPTR, 3, "SelectAddrRegRegScale<3>">;
783 def AddrRegZextRegScale
784     : ComplexPattern<i64, 3, "SelectAddrRegZextRegScale<3, 32>",
785                      [], [], 10>;
787 multiclass LdIdxPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT> {
788 def : Pat<(vt (LoadOp (AddrRegRegScale (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2))),
789           (Inst GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
792 multiclass LdZextIdxPat<PatFrag LoadOp, RVInst Inst, ValueType vt = i64> {
793 def : Pat<(vt (LoadOp (AddrRegZextRegScale (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2))),
794           (Inst GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
797 multiclass StIdxPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
798                     ValueType vt = XLenVT> {
799 def : Pat<(StoreOp (vt StTy:$rd),
800             (AddrRegRegScale (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2)),
801           (Inst StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
804 multiclass StZextIdxPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
805                         ValueType vt = i64> {
806 def : Pat<(StoreOp (vt StTy:$rd),
807             (AddrRegZextRegScale (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2)),
808           (Inst StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
811 let Predicates = [HasVendorXTHeadMemIdx] in {
812 defm : LdIdxPat<extloadi8, TH_LRB>;
813 defm : LdIdxPat<sextloadi8, TH_LRB>;
814 defm : LdIdxPat<zextloadi8, TH_LRBU>;
816 defm : LdIdxPat<extloadi16, TH_LRH>;
817 defm : LdIdxPat<sextloadi16, TH_LRH>;
818 defm : LdIdxPat<zextloadi16, TH_LRHU>;
820 defm : StIdxPat<truncstorei8, TH_SRB, GPR>;
821 defm : StIdxPat<truncstorei16, TH_SRH, GPR>;
824 let Predicates = [HasVendorXTHeadMemIdx, IsRV32] in {
825 defm : LdIdxPat<load, TH_LRW, i32>;
826 defm : StIdxPat<store, TH_SRW, GPR, i32>;
829 let Predicates = [HasVendorXTHeadMemIdx, IsRV64] in {
830 defm : LdZextIdxPat<extloadi8, TH_LURB>;
831 defm : LdZextIdxPat<sextloadi8, TH_LURB>;
832 defm : LdZextIdxPat<zextloadi8, TH_LURBU>;
834 defm : LdZextIdxPat<extloadi16, TH_LURH>;
835 defm : LdZextIdxPat<sextloadi16, TH_LURH>;
836 defm : LdZextIdxPat<zextloadi16, TH_LURHU>;
838 defm : LdIdxPat<extloadi32, TH_LRW, i64>;
839 defm : LdIdxPat<sextloadi32, TH_LRW, i64>;
840 defm : LdIdxPat<zextloadi32, TH_LRWU, i64>;
842 defm : LdZextIdxPat<extloadi32, TH_LURW>;
843 defm : LdZextIdxPat<sextloadi32, TH_LURW>;
844 defm : LdZextIdxPat<zextloadi32, TH_LURWU>;
846 defm : LdIdxPat<load, TH_LRD, i64>;
847 defm : LdZextIdxPat<load, TH_LURD>;
849 defm : StZextIdxPat<truncstorei8, TH_SURB, GPR>;
850 defm : StZextIdxPat<truncstorei16, TH_SURH, GPR>;
851 defm : StIdxPat<truncstorei32, TH_SRW, GPR, i64>;
852 defm : StZextIdxPat<truncstorei32, TH_SURW, GPR, i64>;
853 defm : StIdxPat<store, TH_SRD, GPR, i64>;
854 defm : StZextIdxPat<store, TH_SURD, GPR>;
857 let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF] in {
858 defm : LdIdxPat<load, TH_FLRW, f32>;
859 defm : StIdxPat<store, TH_FSRW, FPR32, f32>;
862 let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD] in {
863 defm : LdIdxPat<load, TH_FLRD, f64>;
864 defm : StIdxPat<store, TH_FSRD, FPR64, f64>;
867 let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV64] in {
868 defm : LdZextIdxPat<load, TH_FLURW, f32>;
869 defm : StZextIdxPat<store, TH_FSURW, FPR32, f32>;
872 let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV64] in {
873 defm : LdZextIdxPat<load, TH_FLURD, f64>;
874 defm : StZextIdxPat<store, TH_FSURD, FPR64, f64>;
877 def simm5shl2 : ComplexPattern<XLenVT, 2, "selectSimm5Shl2">;
879 multiclass StoreUpdatePat<PatFrag st, Instruction Inst, ValueType vt = XLenVT> {
880 def : Pat<(st (vt GPR:$rd), GPR:$rs1, (simm5shl2 simm5:$simm5, uimm2:$uimm2)),
881           (Inst GPR:$rd, GPR:$rs1, simm5:$simm5, uimm2:$uimm2)>;
884 let Predicates = [HasVendorXTHeadMemIdx] in {
885 defm : StoreUpdatePat<post_truncsti8, TH_SBIA>;
886 defm : StoreUpdatePat<pre_truncsti8, TH_SBIB>;
887 defm : StoreUpdatePat<post_truncsti16, TH_SHIA>;
888 defm : StoreUpdatePat<pre_truncsti16, TH_SHIB>;
890 defm : StoreUpdatePat<post_store, TH_SWIA, i32>;
891 defm : StoreUpdatePat<pre_store, TH_SWIB, i32>;
894 let Predicates = [HasVendorXTHeadMemIdx, IsRV64] in {
895 defm : StoreUpdatePat<post_truncsti32, TH_SWIA, i64>;
896 defm : StoreUpdatePat<pre_truncsti32, TH_SWIB, i64>;
897 defm : StoreUpdatePat<post_store, TH_SDIA, i64>;
898 defm : StoreUpdatePat<pre_store, TH_SDIB, i64>;
901 //===----------------------------------------------------------------------===//
902 // Experimental RV64 i32 legalization patterns.
903 //===----------------------------------------------------------------------===//
905 let Predicates = [HasVendorXTHeadMemIdx, IsRV64] in {
906 defm : StoreUpdatePat<post_truncsti8, TH_SBIA, i32>;
907 defm : StoreUpdatePat<pre_truncsti8, TH_SBIB, i32>;
908 defm : StoreUpdatePat<post_truncsti16, TH_SHIA, i32>;
909 defm : StoreUpdatePat<pre_truncsti16, TH_SHIB, i32>;